A modern, high-performance HTTP web server library written in C++20, designed for building scalable web applications and APIs.
- Features
- Quick Start
- Examples
- Installation
- API Reference
- Advanced Usage
- Architecture
- Development
- Troubleshooting
- License
- Support
- HTTP/1.1 Support: Full HTTP/1.1 protocol implementation with keep-alive connections
- Modern C++20: Leverages the latest C++ features for performance and safety
- Epoll-based I/O: Efficient event-driven I/O using Linux epoll for high concurrency
- Routing System: Flexible URL routing with parameter extraction and regex support
- Middleware Support: Modular middleware architecture for request/response processing
- Static File Serving: Built-in static file server with MIME type detection
- JSON Support: Native JSON request/response handling
- Thread Pool: Asynchronous request processing with configurable thread pool
- Socket Abstraction: TCP and Unix domain socket support
- MVC Architecture: Model-View-Controller pattern support for structured applications
- Comprehensive Logging: Colored, timestamped logging system with multiple levels and fmt-style formatting
- Comprehensive Testing: Full test suite with unit tests and benchmarks
#include <http/server.h++>
#include <http/options.h++>
int main() {
auto options = http::options({3044, "127.0.0.1", "My Server", "/public"});
http::server app(&options);
http::router router;
router.add("/", http::request::methods::Get,
[](const http::request *req, http::response *res) {
res->with_body("Hello, World!");
});
app.with_routers(&router);
return app.listen();
}
The project includes several comprehensive examples:
- Basic Server - Minimal HTTP server setup
- HTTP Server - Full-featured HTTP server with routing, JSON API, and static files
- MVC Application - Complete MVC web application with frontend/backend separation
- Logging Demo - Comprehensive demonstration of the logging system features
- Git - Version control
- CMake 3.26+ - Build system (as required by CMakeLists.txt)
- C++20 Compiler - GCC 11+ or Clang 12+
- Linux - Currently supports Linux with epoll
- Clone the repository:
git clone git@github.com:dyatlovk/ws_server.git
cd ws_server
- Configure and build (Debug):
cmake --preset=makefile-x86_64-linux-debug
cmake --build --preset=debug-build-linux -j$(nproc)
- Configure and build (Release):
cmake --preset=makefile-x86_64-linux-release
cmake --build --preset=release-build-linux -j$(nproc)
Option | Debug | Release | Description |
---|---|---|---|
CMAKE_BUILD_TYPE | Debug | MinSizeRel | Build optimization level |
SRV_BUILD_EXAMPLES | On | On | Build example applications |
SRV_BUILD_BENCHMARKS | Off | On | Build performance benchmarks |
SRV_BUILD_TESTS | On | Off | Build unit test suite |
# Build with tests enabled (debug mode)
cmake --preset=makefile-x86_64-linux-debug
cmake --build --preset=debug-build-linux -j$(nproc)
# Run the test suite
./build/makefile-x86_64-linux-debug/tests/server_test
# Build with benchmarks enabled (release mode)
cmake --preset=makefile-x86_64-linux-release
cmake --build --preset=release-build-linux -j$(nproc)
# Run benchmarks
./build/makefile-x86_64-linux-release/benchmarks/response/benchmark_response
./build/makefile-x86_64-linux-release/benchmarks/router/benchmark_router
# Examples are built with both debug and release configurations
# Run basic example
./build/makefile-x86_64-linux-debug/examples/basic/basic_example
# Run HTTP server example
./build/makefile-x86_64-linux-debug/examples/http_server/http_server
# Run MVC example
./build/makefile-x86_64-linux-debug/examples/mvc/mvc
# Run logging system demonstration
./build/makefile-x86_64-linux-debug/examples/logging_demo/logging_demo
After building, verify everything works:
# 1. Verify tests pass
./build/makefile-x86_64-linux-debug/tests/server_test --gtest_filter="*headers*"
# 2. Run a simple server test (in background, then test with curl)
./build/makefile-x86_64-linux-debug/examples/basic/basic_example &
SERVER_PID=$!
sleep 1
curl http://127.0.0.1:3044 # Should return "index"
kill $SERVER_PID
# 3. Check benchmark runs without errors
./build/makefile-x86_64-linux-release/benchmarks/response/benchmark_response
# 4. Test logging system
./build/makefile-x86_64-linux-debug/examples/logging_demo/logging_demo
// Server options
http::options options({
3044, // Port
"127.0.0.1", // Host
"My Server", // Server name
"/public" // Static files directory
});
http::server app(&options);
http::router router;
// Simple route
router.add("/", http::request::methods::Get, handler);
// Multiple HTTP methods
router.add("/api/data", {http::request::methods::Get, http::request::methods::Post}, handler);
// Route parameters with regex
router.add("/user/\\d+", http::request::methods::Get, user_handler);
router.add("/blog/\\D+", http::request::methods::Get, blog_handler);
auto handler = [](http::request *req, http::response *res) {
// Access request method
auto method = req->req.method;
// Access URI and parameters
auto uri = req->req.uri;
auto params = req->req.params; // Extracted from regex routes
// HTTP version
auto version = req->req.http_ver;
};
// Text response
res->with_body("Hello, World!");
// JSON response
miniJson::Json json = miniJson::Json::_object{{"key", "value"}};
res->with_json(&json);
// File response
res->with_view("/index.html");
// Redirect
res->with_redirect("/new-location");
// Headers
res->with_header("Content-Type", "application/json");
res->with_added_header("X-Custom", "value");
// Status codes
res->with_status(404, "Not Found");
The server includes a comprehensive logging system with colored output, timestamps, and multiple log levels:
#include <utils/logger.h++>
// Basic logging with different levels
LOG_DEBUG("Detailed diagnostic information: {}", debug_info);
LOG_INFO("General application flow: {}", status);
LOG_WARN("Warning condition: {}", warning_msg);
LOG_ERROR("Error occurred: {}", error_msg);
// Configure log level filtering
utils::Logger::set_level(utils::LogLevel::INFO); // Hide DEBUG messages
utils::Logger::set_level(utils::LogLevel::WARN); // Hide DEBUG and INFO
utils::Logger::set_level(utils::LogLevel::ERROR); // Only show ERROR
// Advanced formatting with fmt-style syntax
LOG_INFO("User {} has {} unread messages", username, count);
LOG_DEBUG("Server stats: CPU={:.1f}%, Memory={:.2f}GB", cpu_usage, memory_gb);
LOG_ERROR("Database connection failed: host={}, port={}, timeout={}ms",
db_host, db_port, timeout);
Level | Color | Description | Output Stream |
---|---|---|---|
DEBUG | Cyan | Detailed diagnostic information | stdout |
INFO | Green | General information about program execution | stdout |
WARN | Yellow | Warning conditions that should be noted | stderr |
ERROR | Red | Error conditions that indicate problems | stderr |
The logging system is already integrated throughout the HTTP server components:
// Server startup and shutdown
LOG_INFO("Server starting on {}:{}", host, port);
LOG_ERROR("Failed to initialize epoll: {}", e.what());
LOG_INFO("Server is shutting down");
// Socket operations (automatically logged)
LOG_DEBUG("Creating inet_socket for {}:{}", host, port);
LOG_INFO("Opening socket for {}:{} (domain={}, type={})", host, port, domain, type);
LOG_ERROR("Failed to create socket: {}", std::strerror(errno));
// Connection handling
LOG_INFO("Accepted connection from client (fd={})", peer);
LOG_DEBUG("Reading from connection fd={}, bufSize={}", conn, bufSize);
The server supports Model-View-Controller patterns for larger applications:
// Controller class
class BlogController {
public:
auto list(http::request *req, http::response *res) -> http::response {
res->with_json(&blog_list);
return *res;
}
auto entry(http::request *req, http::response *res) -> http::response {
auto params = req->req.params;
if (!params.empty()) {
int id = std::atoi(params[0].c_str());
// Load blog entry by ID
}
return *res;
}
};
// Usage
BlogController blog;
router.add("/blog", method::Get,
std::bind(&BlogController::list, &blog, std::placeholders::_1, std::placeholders::_2));
The server automatically serves static files from the configured public directory:
- Automatic MIME type detection
- Efficient file streaming
- Support for common web assets (HTML, CSS, JS, images)
- Configurable document root
- Epoll I/O Multiplexing: Handle thousands of concurrent connections
- Thread Pool: Configurable worker threads for request processing
- Zero-Copy Operations: Efficient memory management
- Connection Keep-Alive: HTTP/1.1 persistent connections
The server provides comprehensive logging capabilities for development and production:
// Development logging - show all messages
#ifdef DEBUG
utils::Logger::set_level(utils::LogLevel::DEBUG);
#else
utils::Logger::set_level(utils::LogLevel::INFO);
#endif
// Production logging with structured messages
LOG_INFO("Request processed: method={}, path='{}', status={}, duration={}ms",
method, path, status_code, duration);
// Error handling with context
try {
// ... server operations
} catch (const std::exception& e) {
LOG_ERROR("Server error: {}", e.what());
}
-
Use appropriate log levels:
DEBUG
: Detailed diagnostic info for developmentINFO
: General application flow and important eventsWARN
: Recoverable issues that should be notedERROR
: Serious problems that need attention
-
Include context in messages:
LOG_ERROR("Failed to process request: client={}, path='{}', error='{}'", client_id, request_path, error_msg);
-
Be mindful of sensitive data - never log passwords or tokens
-
Use structured logging for metrics:
LOG_INFO("Performance metrics: requests={}, avg_time={}ms, errors={}", request_count, avg_response_time, error_count);
- HTTP Parser: RFC-compliant HTTP message parsing
- Socket Layer: Abstraction over TCP and Unix domain sockets
- Epoll Engine: Event-driven I/O for scalability
- Router: URL pattern matching and parameter extraction
- Middleware Stack: Pluggable request/response processing
- Thread Pool: Asynchronous task execution
- Logging System: Colored, timestamped logging with multiple levels and fmt-style formatting
- fmt: Modern C++ formatting library
- MiniJSON: Lightweight JSON parsing and generation
- Reflex: Regular expression engine for routing
├── src/ # Core library source code
│ ├── http/ # HTTP protocol implementation
│ ├── io/ # I/O abstractions (sockets, epoll)
│ ├── stl/ # STL extensions
│ └── utils/ # Utility classes (logging, thread pool)
├── examples/ # Example applications
├── tests/ # Unit test suite
├── benchmarks/ # Performance benchmarks
└── vendor/ # Third-party dependencies
- Code Style: Follow modern C++20 conventions
- Testing: Add tests for new features
- Documentation: Update README and code comments
- Performance: Consider performance implications
# 1. Setup development environment
git clone git@github.com:dyatlovk/ws_server.git
cd ws_server
# 2. Configure for development (debug + tests)
cmake --preset=makefile-x86_64-linux-debug
# 3. Build everything
cmake --build --preset=debug-build-linux -j$(nproc)
# 4. Run tests to ensure everything works
./build/makefile-x86_64-linux-debug/tests/server_test
# 5. Make your changes...
# 6. Rebuild and test
cmake --build --preset=debug-build-linux -j$(nproc)
./build/makefile-x86_64-linux-debug/tests/server_test
# 7. Test performance impact (optional)
cmake --preset=makefile-x86_64-linux-release
cmake --build --preset=release-build-linux -j$(nproc)
./build/makefile-x86_64-linux-release/benchmarks/response/benchmark_response
# 8. Test examples still work
./build/makefile-x86_64-linux-debug/examples/basic/basic_example
The project includes comprehensive tests covering:
- HTTP parsing and generation
- Socket operations
- Routing functionality
- Request/response handling
- Error conditions
Performance benchmarks are available for:
- Response generation speed
- Router matching performance
- Memory usage patterns
- Concurrency handling
CMake version mismatch:
# Ensure you have CMake 3.26+
cmake --version
# On Ubuntu/Debian, you might need to install from Kitware's repository
# if your distribution's CMake is too old
Missing dependencies:
# Ensure you have a C++20 compatible compiler
g++ --version # Should be GCC 11+
clang++ --version # Should be Clang 12+
# On Ubuntu/Debian:
sudo apt update
sudo apt install build-essential cmake git
Build preset not found:
# List available presets
cmake --list-presets
# If presets are not working, try manual configuration
mkdir -p build/manual
cd build/manual
cmake ../.. -DCMAKE_BUILD_TYPE=Debug -DSRV_BUILD_TESTS=ON
make -j$(nproc)
Permission denied when running executables:
# Make sure executables have execute permissions
chmod +x ./build/makefile-x86_64-linux-debug/tests/server_test
Port already in use:
# Check if port is already in use
sudo netstat -tulpn | grep :3044
# Kill process using the port
sudo lsof -ti:3044 | xargs sudo kill -9
Library linking errors:
# Ensure all dependencies are built
make clean
cmake --build --preset=debug-build-linux -j$(nproc)
Tests failing:
# Run specific test categories
./build/makefile-x86_64-linux-debug/tests/server_test --gtest_filter="*HttpParser*"
# Run in verbose mode for debugging
./build/makefile-x86_64-linux-debug/tests/server_test --gtest_verbose
Performance issues:
# Run in release mode for better performance
cmake --preset=makefile-x86_64-linux-release
cmake --build --preset=release-build-linux -j$(nproc)
./build/makefile-x86_64-linux-release/examples/basic/basic_example
Too verbose logging in production:
# Set appropriate log level to reduce output
utils::Logger::set_level(utils::LogLevel::WARN); # Only warnings and errors
utils::Logger::set_level(utils::LogLevel::ERROR); # Only errors
Missing log output:
# Ensure log level allows your messages
utils::Logger::set_level(utils::LogLevel::DEBUG); # Show all messages
# Check if you're using the correct macros
LOG_INFO("This message will appear"); # Correct
fmt::println("This bypasses logging system"); # Bypasses logging
Log colors not showing:
# Ensure terminal supports ANSI colors
echo $TERM # Should show color-capable terminal like xterm-256color
# Test color support
./build/makefile-x86_64-linux-debug/examples/logging_demo/logging_demo
This project is open source. Please check the repository for license details.
- Issues: Report bugs and feature requests on GitHub
- Documentation: Additional examples in the
examples/
directory - Community: Contributions and feedback welcome
Note: This server is designed for Linux environments and requires epoll support. Windows and macOS support may be added in future versions.