A simple, fast HTTP/1.1 static file server built with modern C++20. Features multi-threaded request handling, security protections, and zero external dependencies.
- HTTP/1.1 Compliant: Proper status lines, headers, and response formatting
- Multi-threaded: Configurable thread pool for concurrent request handling
- Security: Path traversal protection and docroot sandboxing
- MIME Types: Automatic content-type detection for common file types
- Zero Dependencies: Built with standard C++20 and POSIX APIs only
- Graceful Shutdown: SIGINT handling for clean server termination
- Comprehensive Logging: Configurable log levels with timestamps
GET- Retrieve filesHEAD- Retrieve headers only
- HTML:
.html,.htm - CSS:
.css - JavaScript:
.js,.mjs - Images:
.png,.jpg,.jpeg,.gif,.ico,.svg,.webp - Text:
.txt,.md - JSON:
.json - WebAssembly:
.wasm - Fonts:
.woff,.woff2,.ttf,.otf - Archives:
.zip,.tar,.gz - Documents:
.pdf,.xml,.rss,.atom - Default:
application/octet-stream
- Compiler: GCC 10+ or Clang 12+ with C++20 support
- CMake: 3.16 or higher
- OS: Linux or macOS (POSIX-compliant)
- Dependencies: None (uses only standard libraries)
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j# Single-threaded (Phase 1)
./tinyhttp --host 127.0.0.1 --port 8080 --threads 1 --docroot ../public
# Multi-threaded (Phase 2)
./tinyhttp --port 8080 --threads 8 --docroot ../public# Quick test
curl -i http://127.0.0.1:8080/
# Run automated smoke tests
./scripts/smoke_test.shAll options are optional with sensible defaults:
| Option | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Host to bind to |
--port |
8080 |
Port to bind to |
--threads |
1 |
Number of worker threads |
--docroot |
public |
Document root directory |
--backlog |
128 |
Listen backlog |
--log-level |
info |
Log level: debug, info, warn, error |
--help |
- | Show help message |
# Serve files from current directory
./tinyhttp --docroot . --port 3000
# Multi-threaded server with debug logging
./tinyhttp --threads 4 --log-level debug --port 9000
# Custom host and port
./tinyhttp --host 0.0.0.0 --port 80 --docroot /var/www/html# Use the development script
./scripts/run_dev.sh# Test basic functionality
curl -i http://127.0.0.1:8080/
# Test static file serving
curl -i http://127.0.0.1:8080/hello.txt
# Test 404 handling
curl -i http://127.0.0.1:8080/nonexistent
# Test HEAD request
curl -I http://127.0.0.1:8080/
# Test path traversal protection
curl -i http://127.0.0.1:8080/../../etc/passwd# Single-threaded
./tinyhttp --threads 1 --port 8080 &
ab -n 1000 -c 10 http://127.0.0.1:8080/
# Multi-threaded
./tinyhttp --threads 8 --port 8080 &
ab -n 1000 -c 10 http://127.0.0.1:8080/wrk -t12 -c400 -d30s http://127.0.0.1:8080/- Main thread accepts connections and handles requests sequentially
- Simple and reliable for low-traffic scenarios
- Fixed-size thread pool with mutex-protected job queue
- Main thread accepts connections and enqueues client FDs
- Worker threads process requests concurrently
- Graceful shutdown with proper cleanup
- Server: Socket management and request routing
- ThreadPool: Concurrent request processing
- HTTP: Request parsing and response building
- MIME: Content-type detection
- Util: Logging, date formatting, and utilities
- Path Traversal Protection: Prevents
../attacks - Docroot Sandboxing: Files served only from specified directory
- Request Size Limits: 16KB header limit to prevent DoS
- Method Validation: Only GET and HEAD methods allowed
- 400 Bad Request: Malformed HTTP requests
- 404 Not Found: File not found or path traversal attempt
- 405 Method Not Allowed: Unsupported HTTP methods
- 500 Internal Server Error: Server-side errors
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . -j- Address Sanitizer (ASan)
- Undefined Behavior Sanitizer (UBSan)
- Debug symbols (
-g) - No optimization (
-O0)
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . -j- Full optimization (
-O3) - No debug symbols
- NDEBUG defined
.
├── CMakeLists.txt # Build configuration
├── README.md # This file
├── .gitignore # Git ignore rules
├── .clang-format # Code formatting
├── public/ # Default document root
│ ├── index.html # Welcome page
│ ├── 404.html # Custom 404 page
│ └── hello.txt # Test file
├── src/ # Source code
│ ├── main.cpp # Entry point
│ ├── server.hpp/cpp # Server implementation
│ ├── thread_pool.hpp/cpp # Thread pool
│ ├── http.hpp/cpp # HTTP parsing/response
│ ├── mime.hpp/cpp # MIME type handling
│ └── util.hpp/cpp # Utilities
├── scripts/ # Helper scripts
│ ├── run_dev.sh # Development runner
│ └── smoke_test.sh # Automated tests
└── tests/ # Test documentation
└── curl_smoke.md # Manual test cases
- Follow the existing code style (see
.clang-format) - Add tests for new features
- Update documentation as needed
- Ensure all tests pass before submitting
This project is licensed under the Apache-2.0 License - see the LICENSE file for details.
- Built with modern C++20 features
- Uses POSIX socket APIs for cross-platform compatibility
- Inspired by simple HTTP server implementations
- Designed for educational and development purposes