Skip to the content.

< Previous: Advanced Usage | 🏠 Home | Next: Architecture & Examples >


Performance, Tuning, and SSL/TLS

HttpServer exposes its underlying cpptcpnet::TcpListener instance via the GetListener() method. This allows you to configure socket options, apply connection profiles, enable SSL/TLS, and track network performance metrics exactly as you would in a raw TCP application.


1. Accessing the Listener

To configure or query the underlying network layer, call server.GetListener():

cpphttp::HttpServer server(8080);

// Get a reference to the underlying TcpListener
cpptcpnet::TcpListener& listener = server.GetListener();

2. SSL/TLS Encryption

To secure HTTP traffic (HTTPS), configure the underlying TCP listener with SSL certificates before starting the server:

#ifdef CPPTCPNET_SSL_SUPPORT
    cpptcpnet::TcpListener::SslConfig ssl_config;
    ssl_config.cert_file = "certs/server.crt";
    ssl_config.key_file = "certs/server.key";
    
    // Optional: enable mutual TLS (mTLS)
    ssl_config.require_client_cert = false;

    // Enable SSL on the underlying listener
    server.GetListener().EnableSSL(ssl_config);
#endif

3. Performance Tuning & Socket Options

You can fine-tune socket-level settings to optimize HTTP performance for your network conditions:

// Disable Nagle's algorithm (lower latency for small responses)
server.GetListener().SetNoDelay(true);

// Set kernel buffer sizes
server.GetListener().SetSocketRecvBufferSize(65536);
server.GetListener().SetSocketSendBufferSize(65536);

// Tune TCP Keep-Alives
cpptcpnet::KeepAliveConfig ka;
ka.enabled = true;
ka.idle_secs = 60;
ka.interval_secs = 15;
ka.count = 4;
server.GetListener().SetKeepAliveConfig(ka);

Connection Profiles

You can also apply preset ConnectionProfile configurations:

// Apply ReliableLAN profile for local high-speed routing
server.GetListener().SetDefaultConnectionProfile(
    cpptcpnet::ConnectionProfile::ReliableLAN()
);

WebSocket Connection Profiles

You can apply dynamic connection profiles on the fly to individual sessions. When using WebSockets, you can configure unique keep-alive, idle timeout, and Nagle options via WebSocketBehavior::connection_profile, which are applied automatically upon upgrading:

cpphttp::WebSocketBehavior ws_behavior;

// Override default WebSocket profile settings (defaults to interactive LAN)
ws_behavior.connection_profile.no_delay = true;
ws_behavior.connection_profile.idle_timeout = std::chrono::hours(2); // keep open for 2 hours

server.WebSocket("/ws", std::move(ws_behavior));

Configuring Request, Timeout, and Redirect Limits

To protect servers and clients against memory-exhaustion and slow-rate DoS attacks, or to customize request timeouts and redirect behavior:

// 1. Configure HttpServer
server.SetMaxHeaderSize(16384);          // Allow up to 16KB headers (default: 8KB)
server.SetMaxBodySize(50 * 1024 * 1024); // Reject bodies larger than 50MB (default: 10MB)
server.SetIdleTimeout(std::chrono::milliseconds(30000)); // Set idle worker timeout (default: 60s)

// 2. Configure HttpClient
cpphttp::HttpClient client("127.0.0.1", 8080);
client.SetTimeout(std::chrono::seconds(5)); // Timeout requests after 5 seconds
client.SetMaxBodySize(10 * 1024 * 1024);    // Reject response bodies larger than 10MB (default: 10MB)
client.SetMaxRedirects(10);                 // Set max redirects followed (default: 5)

// 3. Configure WebSocketClient
cpphttp::WebSocketClient ws_client;
ws_client.SetMaxBodySize(20 * 1024 * 1024); // Set max WebSocket frame size limit (default: 16MB)
ws_client.SetCloseTimeout(std::chrono::milliseconds(2000)); // Set WebSocket close handshake timeout (default: 1s)

Thread Pool Tuning (HttpServer)

HttpServer relies on cpp-tcpnet’s internal worker pool to dispatch received data. By default, it uses std::thread::hardware_concurrency() worker threads. The worker pool uses session-affinity hashing \u2014 each connection is pinned to a specific thread (via session_id % num_threads), so multiple threads can run in parallel without corrupting per-connection state.

You can tune the server’s worker thread count via the underlying listener:

cpphttp::HttpServer server(8080);

// Use a fixed number of worker threads (default: hardware concurrency)
server.GetListener().SetWorkerThreadCount(4);

server.Start();

Note: Because session-affinity is maintained, all thread count values ≥ 1 are safe. Higher counts increase parallelism across simultaneous connections; there is no need to set it to 1 for ordering correctness.

Thread Pool Tuning (HttpClient)

By default, all instances of HttpClient share a global background cppasyncworker::WorkerPool for processing asynchronous requests (GetAsync, PostAsync, etc.). You can customize the size of this global worker pool or pass a custom pool to individual clients:

// 1. Customize the size of the global background thread pool
cpphttp::SetClientWorkerPoolSize(8); // Spawn 8 worker threads for shared async HTTP tasks (defaults to hardware concurrency, min: 4)

// 2. Or, construct an HttpClient using a fully custom, independent worker pool
auto my_pool = std::make_shared<cppasyncworker::WorkerPool>(16);
cpphttp::HttpClient client("127.0.0.1", 8080, my_pool);

4. Throughput Tracking

You can monitor real-time HTTP upload and download rates (bytes/second) by passing the listener’s event broker to the ThroughputTracker utility:

#include "cpphttp.hpp"
#include <iostream>
#include <thread>

int main() {
    cpphttp::HttpServer server(8080);
    server.Start();

    // Track throughput over a 1-second sliding window
    cpptcpnet::ThroughputTracker tracker(
        server.GetListener().GetEventBroker(), 
        std::chrono::seconds(1)
    );

    // Monitor in a background loop
    std::thread([&tracker]() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << "Upload rate: " << tracker.GetSendThroughputBytesPerSec() << " B/s | "
                      << "Download rate: " << tracker.GetRecvThroughputBytesPerSec() << " B/s\n";
        }
    }).detach();

    std::cin.get();
    server.Stop();
}

5. Direct Stats (Atomic Counters)

At any time, you can query cumulative bytes/packets handled by the server:

cpptcpnet::ListenerStats stats = server.GetListener().GetStats();

std::cout << "Active HTTP Connections: " << stats.active_connections << "\n"
          << "Total Bytes Transmitted: " << stats.bytes_sent << " bytes\n"
          << "Total Bytes Received:    " << stats.bytes_received << " bytes\n";

< Previous: Advanced Usage | 🏠 Home | Next: Architecture & Examples >