cpp-httplib

Header-only HTTP client and server library for C++11. Easy integration with single header file. Compactly provides HTTP/HTTPS support, SSL/TLS, multipart, range requests, basic authentication, and JSON processing capabilities.

HTTP ClientC++Header-onlyServerClientSSL/TLS

GitHub Overview

yhirose/cpp-httplib

A C++ header-only HTTP/HTTPS server and client library

Stars15,091
Watchers189
Forks2,519
Created:September 22, 2012
Language:C++
License:MIT License

Topics

cppcpp11header-onlyhttphttps

Star History

yhirose/cpp-httplib Star History
Data as of: 10/22/2025, 09:55 AM

Library

cpp-httplib

Overview

cpp-httplib is "a C++11 compliant single-file header-only HTTP/HTTPS library" developed as one of the most easily integrated C++ HTTP libraries. With the concept of "simple and user-friendly," it provides HTTP server and client functionality by simply including a single header file (httplib.h). Offering intuitive programming model with blocking socket I/O, multi-platform support, SSL/TLS encryption support, and comprehensive features necessary for HTTP communication in C++ applications, it serves as an ideal choice for developers who prioritize lightweight design and ease of use.

Details

cpp-httplib 2025 edition has established itself as a mature HTTP library providing the best integration experience in C++11+ environments. With over 15 years of development experience, it boasts refined APIs and high stability, being widely adopted across Windows, Linux, and macOS environments. The single-header design minimizes external dependencies, making project integration extremely simple. With a simple programming model using blocking I/O, both HTTP server and client functionality can be implemented intuitively. It meets enterprise-level HTTP communication requirements including HTTPS support through OpenSSL, multipart form data processing, authentication systems, and proxy support.

Key Features

  • Header-only Design: Complete functionality with just the httplib.h file
  • Server & Client Integration: Bidirectional HTTP communication in a single library
  • C++11 Compliance: Full compliance with modern C++ standards
  • Multi-platform Support: Complete support for Windows, Linux, and macOS
  • SSL/TLS Encryption: Complete HTTPS support through OpenSSL 3.0+
  • Blocking I/O: Easy-to-understand synchronous programming model

Pros and Cons

Pros

  • Extremely simple integration process with minimal dependency management
  • Simplified distribution and deployment through single-header design
  • High learning efficiency and code readability through intuitive API
  • Unified library providing both server and client functionality
  • Predictable execution flow through blocking I/O model
  • Rich HTTP feature support (authentication, proxy, multipart, etc.)

Cons

  • Concurrent connection limitations due to blocking I/O (unsuitable for high throughput)
  • Resource consumption in high-concurrency processing due to thread pool dependency
  • Performance disadvantage compared to asynchronous I/O libraries
  • External library requirement due to OpenSSL dependency for HTTPS usage
  • Scalability limitations for I/O-intensive applications
  • Feature/performance trade-offs for applications requiring maximum performance

Reference Pages

Code Examples

Installation and Basic Setup

// Using cpp-httplib (header-only)
#include "httplib.h"

// Enable OpenSSL support for HTTPS
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include "httplib.h"

// Compilation example (Linux/macOS)
// g++ -std=c++11 your_app.cpp -pthread

// Link options for HTTPS
// g++ -std=c++11 your_app.cpp -pthread -lssl -lcrypto

// CMake dependency configuration
/*
find_package(httplib REQUIRED)
target_link_libraries(your_target httplib::httplib)
*/

Basic HTTP Client (GET/POST/PUT/DELETE)

#include "httplib.h"
#include <iostream>

int main() {
    // Create HTTP client
    httplib::Client client("https://api.example.com");
    
    // Basic GET request
    auto res = client.Get("/users");
    if (res) {
        if (res->status == 200) {
            std::cout << "Status: " << res->status << std::endl;
            std::cout << "Content-Type: " << res->get_header_value("content-type") << std::endl;
            std::cout << "Body: " << res->body << std::endl;
        }
    } else {
        auto err = res.error();
        std::cout << "HTTP error: " << httplib::to_string(err) << std::endl;
    }
    
    // GET request with query parameters
    httplib::Params params = {
        {"page", "1"},
        {"limit", "10"},
        {"sort", "created_at"}
    };
    res = client.Get("/users", params, httplib::Headers{});
    
    // POST request (sending JSON)
    std::string json_data = R"({
        "name": "John Doe",
        "email": "[email protected]",
        "age": 30
    })";
    
    httplib::Headers headers = {
        {"Content-Type", "application/json"},
        {"Authorization", "Bearer your-token"}
    };
    
    res = client.Post("/users", headers, json_data, "application/json");
    if (res && res->status == 201) {
        std::cout << "User created successfully: " << res->body << std::endl;
    } else {
        std::cout << "Error: " << (res ? std::to_string(res->status) : "Connection failed") << std::endl;
    }
    
    // POST request (sending form data)
    httplib::Params form_data = {
        {"username", "testuser"},
        {"password", "secret123"}
    };
    res = client.Post("/login", form_data);
    
    // PUT request (data update)
    std::string update_json = R"({"name": "Jane Doe", "email": "[email protected]"})";
    res = client.Put("/users/123", headers, update_json, "application/json");
    
    // DELETE request
    res = client.Delete("/users/123", headers);
    if (res && res->status == 204) {
        std::cout << "User deleted successfully" << std::endl;
    }
    
    // Detailed response information inspection
    if (res) {
        std::cout << "Status: " << res->status << std::endl;
        std::cout << "Reason: " << res->reason << std::endl;
        std::cout << "Headers:" << std::endl;
        for (const auto& [key, value] : res->headers) {
            std::cout << "  " << key << ": " << value << std::endl;
        }
    }
    
    return 0;
}

Advanced Configuration and Customization (Headers, Authentication, Timeout, etc.)

#include "httplib.h"
#include <chrono>

void advanced_client_configuration() {
    // Create HTTPS client
    httplib::Client client("https://secure-api.example.com");
    
    // Custom header configuration
    httplib::Headers custom_headers = {
        {"User-Agent", "MyApp/1.0 (cpp-httplib)"},
        {"Accept", "application/json"},
        {"Accept-Language", "en-US,ja-JP"},
        {"X-API-Version", "v2"},
        {"X-Request-ID", "req-12345"}
    };
    
    // Set default headers
    client.set_default_headers(custom_headers);
    
    // Basic authentication setup
    client.set_basic_auth("username", "password");
    
    // Bearer Token authentication
    client.set_bearer_token_auth("your-jwt-token");
    
    // Digest authentication (requires OpenSSL)
    client.set_digest_auth("username", "password");
    
    // Timeout configuration
    client.set_connection_timeout(0, 300000); // Connection timeout 300ms
    client.set_read_timeout(5, 0);            // Read timeout 5 seconds
    client.set_write_timeout(5, 0);           // Write timeout 5 seconds
    
    // SSL certificate configuration
    client.set_ca_cert_path("./ca-bundle.crt");        // CA certificate bundle
    client.enable_server_certificate_verification(true); // Enable certificate verification
    client.enable_server_hostname_verification(true);    // Enable hostname verification
    
    // Disable SSL verification for development (not recommended)
    // client.enable_server_certificate_verification(false);
    
    // Proxy configuration
    client.set_proxy("proxy.example.com", 8080);
    client.set_proxy_basic_auth("proxy_user", "proxy_pass");
    
    // Keep-Alive configuration
    client.set_keep_alive(true);
    
    // Redirect following configuration
    client.set_follow_location(true);
    
    // Compression configuration
    client.set_compress(true);      // Request compression
    client.set_decompress(true);    // Response auto-decompression
    
    // Network interface specification (Linux/macOS)
    client.set_interface("eth0");
    
    // Request execution example
    auto res = client.Get("/secure-data");
    if (res) {
        std::cout << "Secure request successful: " << res->status << std::endl;
    }
}

// Custom authentication header implementation
class APIKeyAuth {
private:
    std::string api_key;
    std::string header_name;
    
public:
    APIKeyAuth(const std::string& key, const std::string& header = "X-API-Key")
        : api_key(key), header_name(header) {}
    
    httplib::Headers get_headers() const {
        return {{header_name, api_key}};
    }
};

void custom_authentication_example() {
    httplib::Client client("https://api.example.com");
    
    // Using custom authentication
    APIKeyAuth auth("your-api-key-here");
    auto headers = auth.get_headers();
    
    auto res = client.Get("/protected-data", headers);
    if (res) {
        std::cout << "Authenticated request: " << res->status << std::endl;
    }
}

Error Handling and Retry Functionality

#include "httplib.h"
#include <chrono>
#include <thread>
#include <stdexcept>

// Comprehensive error handling
class HTTPClient {
private:
    httplib::Client client;
    int max_retries;
    std::chrono::milliseconds base_delay;
    
public:
    HTTPClient(const std::string& host, int port = -1, int retries = 3) 
        : client(host, port), max_retries(retries), base_delay(1000) {
        
        // Basic configuration
        client.set_connection_timeout(0, 300000); // 300ms
        client.set_read_timeout(10, 0);          // 10 seconds
        client.set_write_timeout(10, 0);         // 10 seconds
    }
    
    httplib::Result safe_get(const std::string& path, 
                            const httplib::Headers& headers = {},
                            const httplib::Params& params = {}) {
        
        for (int attempt = 0; attempt <= max_retries; ++attempt) {
            auto res = client.Get(path, params, headers);
            
            if (res) {
                // Successful response case
                if (res->status >= 200 && res->status < 300) {
                    return res;
                }
                
                // Determine retry-eligible status codes
                if (res->status == 429 || res->status == 500 || 
                    res->status == 502 || res->status == 503 || res->status == 504) {
                    
                    if (attempt < max_retries) {
                        auto delay = base_delay * (1 << attempt); // Exponential backoff
                        std::cout << "Retry " << (attempt + 1) << "/" << max_retries 
                                 << " (Status: " << res->status << ") "
                                 << "after " << delay.count() << "ms..." << std::endl;
                        std::this_thread::sleep_for(delay);
                        continue;
                    }
                }
                
                // Non-retryable error or max attempts reached
                return res;
            } else {
                // Connection error case
                auto error = res.error();
                std::cout << "Connection error: " << httplib::to_string(error) << std::endl;
                
                if (attempt < max_retries) {
                    auto delay = base_delay * (1 << attempt);
                    std::cout << "Connection retry " << (attempt + 1) << "/" << max_retries 
                             << " after " << delay.count() << "ms..." << std::endl;
                    std::this_thread::sleep_for(delay);
                    continue;
                }
            }
        }
        
        // All attempts failed
        return httplib::Result{nullptr, httplib::Error::Unknown};
    }
    
    void handle_response(const httplib::Result& res) {
        if (!res) {
            auto error = res.error();
            
            switch (error) {
                case httplib::Error::Connection:
                    std::cerr << "Connection error: Cannot connect to server" << std::endl;
                    break;
                case httplib::Error::BindIPAddress:
                    std::cerr << "IP address bind error" << std::endl;
                    break;
                case httplib::Error::Read:
                    std::cerr << "Read error: Failed to receive data" << std::endl;
                    break;
                case httplib::Error::Write:
                    std::cerr << "Write error: Failed to send data" << std::endl;
                    break;
                case httplib::Error::ExceedRedirectCount:
                    std::cerr << "Redirect error: Exceeded redirect limit" << std::endl;
                    break;
                case httplib::Error::Canceled:
                    std::cerr << "Request canceled" << std::endl;
                    break;
                case httplib::Error::SSLConnection:
                    std::cerr << "SSL connection error: HTTPS connection failed" << std::endl;
                    break;
                case httplib::Error::SSLLoadingCerts:
                    std::cerr << "SSL certificate loading error" << std::endl;
                    break;
                case httplib::Error::SSLServerVerification:
                    std::cerr << "SSL certificate verification error" << std::endl;
                    break;
                case httplib::Error::UnsupportedMultipartBoundaryChars:
                    std::cerr << "Multipart boundary character error" << std::endl;
                    break;
                default:
                    std::cerr << "Unknown error: " << httplib::to_string(error) << std::endl;
                    break;
            }
            return;
        }
        
        // Status code-specific handling
        switch (res->status) {
            case 200:
                std::cout << "Success: " << res->body << std::endl;
                break;
            case 201:
                std::cout << "Created successfully: " << res->body << std::endl;
                break;
            case 204:
                std::cout << "Processing completed (no response)" << std::endl;
                break;
            case 400:
                std::cerr << "Bad request: " << res->body << std::endl;
                break;
            case 401:
                std::cerr << "Authentication error: Please check your token" << std::endl;
                break;
            case 403:
                std::cerr << "Permission error: Access denied" << std::endl;
                break;
            case 404:
                std::cerr << "Not found: Resource does not exist" << std::endl;
                break;
            case 429:
                std::cerr << "Rate limit: Please wait before retrying" << std::endl;
                break;
            case 500:
                std::cerr << "Server error: Problem on server side" << std::endl;
                break;
            default:
                if (res->status >= 400) {
                    std::cerr << "HTTP error " << res->status << ": " << res->body << std::endl;
                } else {
                    std::cout << "Response " << res->status << ": " << res->body << std::endl;
                }
                break;
        }
    }
};

void error_handling_example() {
    try {
        HTTPClient client("https://api.example.com");
        
        // Normal request
        auto res = client.safe_get("/users");
        client.handle_response(res);
        
        // Potentially failing request
        res = client.safe_get("/unstable-endpoint");
        client.handle_response(res);
        
    } catch (const std::exception& e) {
        std::cerr << "Exception occurred: " << e.what() << std::endl;
    }
}

Basic HTTP Server Implementation

#include "httplib.h"
#include <iostream>
#include <fstream>
#include <json/json.h>  // When using JsonCpp

class SimpleHTTPServer {
private:
    httplib::Server server;
    
public:
    SimpleHTTPServer() {
        setup_routes();
        setup_middleware();
    }
    
    void setup_routes() {
        // Basic GET endpoint
        server.Get("/hello", [](const httplib::Request& req, httplib::Response& res) {
            res.set_content("Hello, World!", "text/plain");
        });
        
        // JSON response
        server.Get("/api/users", [](const httplib::Request& req, httplib::Response& res) {
            std::string json_response = R"({
                "users": [
                    {"id": 1, "name": "John Doe", "email": "[email protected]"},
                    {"id": 2, "name": "Jane Smith", "email": "[email protected]"}
                ]
            })";
            res.set_content(json_response, "application/json");
        });
        
        // Route with path parameters
        server.Get(R"(/api/users/(\d+))", [](const httplib::Request& req, httplib::Response& res) {
            auto user_id = req.matches[1];
            std::string response = "User ID: " + std::string(user_id);
            res.set_content(response, "text/plain");
        });
        
        // Named path parameters
        server.Get("/users/:id", [](const httplib::Request& req, httplib::Response& res) {
            auto user_id = req.path_params.at("id");
            std::string response = "User ID: " + user_id;
            res.set_content(response, "text/plain");
        });
        
        // POST endpoint (JSON reception)
        server.Post("/api/users", [](const httplib::Request& req, httplib::Response& res) {
            // Content-Type check
            if (req.get_header_value("Content-Type") != "application/json") {
                res.status = 400;
                res.set_content("Content-Type must be application/json", "text/plain");
                return;
            }
            
            // Process request body
            std::cout << "Received JSON: " << req.body << std::endl;
            
            // Create response
            std::string response_json = R"({
                "status": "success",
                "message": "User created successfully",
                "id": 123
            })";
            
            res.status = 201;
            res.set_content(response_json, "application/json");
        });
        
        // Multipart form data processing
        server.Post("/upload", [](const httplib::Request& req, httplib::Response& res) {
            if (req.is_multipart_form_data()) {
                for (const auto& file : req.files) {
                    std::cout << "File: " << file.first << std::endl;
                    std::cout << "  Filename: " << file.second.filename << std::endl;
                    std::cout << "  Content-Type: " << file.second.content_type << std::endl;
                    std::cout << "  Size: " << file.second.content.size() << " bytes" << std::endl;
                    
                    // Save file
                    std::ofstream ofs("./uploads/" + file.second.filename, std::ios::binary);
                    ofs << file.second.content;
                }
                
                res.set_content("Files uploaded successfully", "text/plain");
            } else {
                res.status = 400;
                res.set_content("Expected multipart/form-data", "text/plain");
            }
        });
        
        // Streaming response
        server.Get("/stream", [](const httplib::Request& req, httplib::Response& res) {
            res.set_chunked_content_provider(
                "text/plain",
                [](size_t offset, httplib::DataSink& sink) {
                    static int count = 0;
                    if (count < 10) {
                        std::string chunk = "Chunk " + std::to_string(count++) + "\n";
                        sink.write(chunk.c_str(), chunk.size());
                        return true;  // Continue
                    } else {
                        sink.done();
                        return false; // Complete
                    }
                }
            );
        });
        
        // Static file server
        server.set_mount_point("/static", "./public");
        
        // Server stop endpoint
        server.Get("/stop", [&](const httplib::Request& req, httplib::Response& res) {
            res.set_content("Server stopping...", "text/plain");
            server.stop();
        });
    }
    
    void setup_middleware() {
        // Request logger
        server.set_logger([](const httplib::Request& req, const httplib::Response& res) {
            std::cout << "[" << std::chrono::duration_cast<std::chrono::seconds>(
                std::chrono::system_clock::now().time_since_epoch()).count() 
                << "] " << req.method << " " << req.path 
                << " -> " << res.status << std::endl;
        });
        
        // CORS configuration
        server.set_pre_routing_handler([](const httplib::Request& req, httplib::Response& res) {
            res.set_header("Access-Control-Allow-Origin", "*");
            res.set_header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            res.set_header("Access-Control-Allow-Headers", "Content-Type, Authorization");
            
            if (req.method == "OPTIONS") {
                res.status = 200;
                return httplib::Server::HandlerResponse::Handled;
            }
            return httplib::Server::HandlerResponse::Unhandled;
        });
        
        // Error handler
        server.set_error_handler([](const httplib::Request& req, httplib::Response& res) {
            std::string error_html = "<html><body><h1>Error " + 
                std::to_string(res.status) + "</h1><p>Something went wrong</p></body></html>";
            res.set_content(error_html, "text/html");
        });
        
        // Exception handler
        server.set_exception_handler([](const httplib::Request& req, httplib::Response& res, std::exception_ptr ep) {
            try {
                std::rethrow_exception(ep);
            } catch (const std::exception& e) {
                res.status = 500;
                std::string error_msg = "Internal Server Error: " + std::string(e.what());
                res.set_content(error_msg, "text/plain");
            } catch (...) {
                res.status = 500;
                res.set_content("Unknown Internal Server Error", "text/plain");
            }
        });
    }
    
    void run(const std::string& host = "localhost", int port = 8080) {
        std::cout << "Server starting: http://" << host << ":" << port << std::endl;
        
        if (!server.listen(host, port)) {
            std::cerr << "Server start failed" << std::endl;
        }
    }
};

int main() {
    SimpleHTTPServer server;
    server.run("0.0.0.0", 8080);
    return 0;
}

Advanced Features (File Upload, Streaming, Authentication)

#include "httplib.h"
#include <fstream>
#include <filesystem>
#include <jwt-cpp/jwt.h>  // When using JWT authentication library

class AdvancedHTTPServer {
private:
    httplib::Server server;
    std::string jwt_secret = "your-secret-key";
    
public:
    AdvancedHTTPServer() {
        setup_advanced_routes();
        configure_server();
    }
    
    bool verify_jwt_token(const std::string& token) {
        try {
            auto decoded = jwt::decode(token);
            auto verifier = jwt::verify()
                .allow_algorithm(jwt::algorithm::hs256{jwt_secret})
                .with_issuer("your-app");
            verifier.verify(decoded);
            return true;
        } catch (const std::exception& e) {
            std::cerr << "JWT verification failed: " << e.what() << std::endl;
            return false;
        }
    }
    
    void setup_advanced_routes() {
        // Endpoint requiring JWT authentication
        server.Get("/api/protected", [this](const httplib::Request& req, httplib::Response& res) {
            std::string auth_header = req.get_header_value("Authorization");
            if (auth_header.empty() || auth_header.substr(0, 7) != "Bearer ") {
                res.status = 401;
                res.set_content("Missing or invalid Authorization header", "text/plain");
                return;
            }
            
            std::string token = auth_header.substr(7);
            if (!verify_jwt_token(token)) {
                res.status = 401;
                res.set_content("Invalid JWT token", "text/plain");
                return;
            }
            
            res.set_content("Protected data: Secret information", "text/plain");
        });
        
        // Large file upload
        server.Post("/api/upload/large", [](const httplib::Request& req, httplib::Response& res) {
            std::string upload_dir = "./uploads";
            std::filesystem::create_directories(upload_dir);
            
            if (req.is_multipart_form_data()) {
                for (const auto& file : req.files) {
                    std::string filepath = upload_dir + "/" + file.second.filename;
                    
                    std::ofstream ofs(filepath, std::ios::binary);
                    if (ofs) {
                        ofs.write(file.second.content.data(), file.second.content.size());
                        std::cout << "File saved: " << filepath 
                                 << " (" << file.second.content.size() << " bytes)" << std::endl;
                    } else {
                        res.status = 500;
                        res.set_content("File save failed", "text/plain");
                        return;
                    }
                }
                
                std::string response = "Upload completed: " + std::to_string(req.files.size()) + " files";
                res.set_content(response, "text/plain");
            } else {
                res.status = 400;
                res.set_content("Expected multipart/form-data", "text/plain");
            }
        });
        
        // Streaming reception with content receiver
        server.Post("/api/upload/stream", [](const httplib::Request& req, httplib::Response& res, 
                   const httplib::ContentReader& content_reader) {
            
            std::string filename = "streamed_file.dat";
            std::ofstream ofs(filename, std::ios::binary);
            
            if (!ofs) {
                res.status = 500;
                res.set_content("Cannot create file", "text/plain");
                return;
            }
            
            size_t total_bytes = 0;
            
            content_reader([&](const char* data, size_t data_length) {
                ofs.write(data, data_length);
                total_bytes += data_length;
                
                // Progress display (every 1MB)
                if (total_bytes % (1024 * 1024) == 0) {
                    std::cout << "Received: " << total_bytes / (1024 * 1024) << " MB" << std::endl;
                }
                
                return true; // Continue
            });
            
            ofs.close();
            
            std::string response = "File received: " + std::to_string(total_bytes) + " bytes";
            res.set_content(response, "text/plain");
        });
        
        // File download (Range Request support)
        server.Get(R"(/api/download/(.+))", [](const httplib::Request& req, httplib::Response& res) {
            std::string filename = req.matches[1];
            std::string filepath = "./downloads/" + filename;
            
            if (!std::filesystem::exists(filepath)) {
                res.status = 404;
                res.set_content("File not found", "text/plain");
                return;
            }
            
            // Get file size
            auto file_size = std::filesystem::file_size(filepath);
            
            // Handle Range Request
            std::string range_header = req.get_header_value("Range");
            if (!range_header.empty()) {
                // Parse "bytes=start-end" format
                size_t start = 0, end = file_size - 1;
                
                if (range_header.substr(0, 6) == "bytes=") {
                    std::string range_spec = range_header.substr(6);
                    auto dash_pos = range_spec.find('-');
                    
                    if (dash_pos != std::string::npos) {
                        if (dash_pos > 0) {
                            start = std::stoull(range_spec.substr(0, dash_pos));
                        }
                        if (dash_pos + 1 < range_spec.length()) {
                            end = std::stoull(range_spec.substr(dash_pos + 1));
                        }
                    }
                }
                
                // Validate range
                if (start >= file_size || end >= file_size || start > end) {
                    res.status = 416; // Range Not Satisfiable
                    res.set_header("Content-Range", "bytes */" + std::to_string(file_size));
                    return;
                }
                
                // Send partial content
                std::ifstream ifs(filepath, std::ios::binary);
                ifs.seekg(start);
                
                size_t content_length = end - start + 1;
                std::vector<char> buffer(content_length);
                ifs.read(buffer.data(), content_length);
                
                res.status = 206; // Partial Content
                res.set_header("Content-Range", "bytes " + std::to_string(start) + "-" + 
                             std::to_string(end) + "/" + std::to_string(file_size));
                res.set_header("Accept-Ranges", "bytes");
                res.set_content(std::string(buffer.data(), content_length), "application/octet-stream");
            } else {
                // Send entire file
                res.set_file_content(filepath);
                res.set_header("Accept-Ranges", "bytes");
            }
        });
        
        // Real-time data streaming
        server.Get("/api/events", [](const httplib::Request& req, httplib::Response& res) {
            res.set_header("Content-Type", "text/event-stream");
            res.set_header("Cache-Control", "no-cache");
            res.set_header("Connection", "keep-alive");
            
            res.set_chunked_content_provider(
                "text/event-stream",
                [](size_t offset, httplib::DataSink& sink) {
                    static int event_count = 0;
                    
                    if (event_count < 10) {
                        auto now = std::chrono::system_clock::now();
                        auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(
                            now.time_since_epoch()).count();
                        
                        std::string event_data = "data: {\"event\": " + std::to_string(event_count) + 
                                               ", \"timestamp\": " + std::to_string(timestamp) + "}\n\n";
                        
                        sink.write(event_data.c_str(), event_data.size());
                        event_count++;
                        
                        std::this_thread::sleep_for(std::chrono::seconds(1));
                        return true;
                    } else {
                        sink.done();
                        return false;
                    }
                }
            );
        });
    }
    
    void configure_server() {
        // Server configuration
        server.set_read_timeout(60, 0);        // 60 seconds
        server.set_write_timeout(60, 0);       // 60 seconds
        server.set_payload_max_length(100 * 1024 * 1024); // 100MB
        server.set_keep_alive_max_count(10);
        server.set_keep_alive_timeout(30);
        
        // Thread pool configuration
        server.new_task_queue = []() {
            return new httplib::ThreadPool(12); // 12 threads
        };
    }
    
    void run_https(const std::string& cert_path, const std::string& key_path, 
                   const std::string& host = "0.0.0.0", int port = 8443) {
        
        httplib::SSLServer ssl_server(cert_path, key_path);
        
        // Copy configuration to HTTPS server
        ssl_server = std::move(server);
        
        std::cout << "HTTPS server starting: https://" << host << ":" << port << std::endl;
        
        if (!ssl_server.listen(host, port)) {
            std::cerr << "HTTPS server start failed" << std::endl;
        }
    }
};

int main() {
    AdvancedHTTPServer server;
    
    // Run as HTTPS server (requires certificate files)
    // server.run_https("./cert.pem", "./key.pem");
    
    return 0;
}