LCOV - code coverage report
Current view: top level - http/server - server_standalone.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 91.3 % 69 63
Test Date: 2026-02-20 15:38:22 Functions: 90.9 % 11 10

            Line data    Source code
       1              : #include "server_standalone.hpp"
       2              : #include "../../util/logger.hpp"
       3              : #include "../../asio/ssl/certificate_manager.hpp"
       4              : #include <future>
       5              : 
       6              : namespace thinger::http {
       7              : 
       8          671 : server::server() {
       9          671 :     LOG_DEBUG("Created standalone HTTP server (single-threaded)");
      10          671 : }
      11              : 
      12          671 : server::~server() {
      13          671 :     LOG_DEBUG("Destroying standalone HTTP server");
      14          671 :     if (running_) {
      15           12 :         stop();
      16              :     }
      17          671 : }
      18              : 
      19              : 
      20          559 : std::unique_ptr<asio::socket_server> server::create_socket_server(
      21              :     const std::string& host, const std::string& port) {
      22              :     
      23              :     // Both acceptor and connections use our io_context
      24         1910 :     auto context_provider = [this]() -> boost::asio::io_context& {
      25         1910 :         return io_context_;
      26          559 :     };
      27              :     
      28              :     auto server = std::make_unique<asio::socket_server>(
      29              :         host, port,
      30              :         context_provider,    // acceptor context
      31              :         context_provider     // connection context
      32          559 :     );
      33              :     
      34              :     // Configure SSL if enabled
      35          559 :     if (ssl_enabled_) {
      36           52 :         server->enable_ssl(true);
      37              :         
      38           52 :         auto& cert_mgr = asio::certificate_manager::instance();
      39           52 :         auto default_ctx = cert_mgr.get_default_certificate();
      40              :         
      41           52 :         if (!default_ctx) {
      42            0 :             LOG_ERROR("No default SSL certificate configured");
      43            0 :             return nullptr;
      44              :         }
      45              : 
      46           52 :         server->set_ssl_context(default_ctx);
      47           52 :         server->set_sni_callback(asio::certificate_manager::sni_callback);
      48           52 :     }
      49              : 
      50          559 :     return server;
      51          559 : }
      52              : 
      53           39 : std::unique_ptr<asio::unix_socket_server> server::create_unix_socket_server(
      54              :     const std::string& unix_path) {
      55              :     
      56              :     // Both acceptor and connections use our io_context
      57           39 :     auto context_provider = [this]() -> boost::asio::io_context& {
      58           39 :         return io_context_;
      59           39 :     };
      60              :     
      61              :     auto server = std::make_unique<asio::unix_socket_server>(
      62              :         unix_path,
      63              :         context_provider,    // acceptor context
      64              :         context_provider     // connection context
      65           39 :     );
      66              :     
      67           78 :     return server;
      68              : }
      69              : 
      70          562 : bool server::listen(const std::string& host, uint16_t port) {
      71          562 :     if (running_) {
      72            3 :         LOG_WARNING("Server already running");
      73            3 :         return false;
      74              :     }
      75              :     
      76              :     // Restart io_context if it was previously stopped
      77          559 :     io_context_.restart();
      78              :     
      79              :     // Call base implementation to setup socket server
      80          559 :     if (!http_server_base::listen(host, port)) {
      81            6 :         return false;
      82              :     }
      83              :     
      84              :     // Create work guard to keep io_context running
      85          553 :     work_guard_ = std::make_unique<work_guard_type>(io_context_.get_executor());
      86              :     
      87              :     // Mark as running
      88          553 :     running_ = true;
      89          553 :     LOG_INFO("Standalone server listening on {}:{} (single-threaded)", host, port);
      90              :     
      91              :     // Note: io_context_.run() will be called in wait() method
      92              :     
      93          553 :     return true;
      94              : }
      95              : 
      96           39 : bool server::listen_unix(const std::string& unix_path) {
      97           39 :     if (running_) {
      98            0 :         LOG_WARNING("Server already running");
      99            0 :         return false;
     100              :     }
     101              : 
     102              :     // Restart io_context if it was previously stopped
     103           39 :     io_context_.restart();
     104              : 
     105              :     // Call base implementation to setup unix socket server
     106           39 :     if (!http_server_base::listen_unix(unix_path)) {
     107            0 :         return false;
     108              :     }
     109              : 
     110              :     // Create work guard to keep io_context running
     111           39 :     work_guard_ = std::make_unique<work_guard_type>(io_context_.get_executor());
     112              : 
     113              :     // Mark as running
     114           39 :     running_ = true;
     115           39 :     LOG_INFO("Standalone server listening on unix:{} (single-threaded)", unix_path);
     116              : 
     117           39 :     return true;
     118              : }
     119              : 
     120          571 : void server::wait() {
     121          571 :     if (!running_) {
     122            0 :         return;
     123              :     }
     124              :     
     125              :     // Run io_context in the current thread
     126              :     // This blocks until the server is stopped
     127          571 :     LOG_DEBUG("Running io_context in current thread");
     128          571 :     io_context_.run();
     129          571 :     LOG_DEBUG("io_context stopped");
     130              : }
     131              : 
     132          597 : bool server::stop() {
     133          597 :     if (!running_) {
     134            5 :         return false;
     135              :     }
     136              :     
     137          592 :     LOG_DEBUG("Stopping standalone HTTP server");
     138          592 :     running_ = false;
     139              :     
     140              :     // Stop accepting new connections first (this is always safe to call)
     141          592 :     http_server_base::stop();
     142              :     
     143              :     // Reset work guard to allow io_context to stop when it's running
     144          592 :     work_guard_.reset();
     145              :     
     146              :     // Stop the io_context if it's running
     147              :     // Note: io_context_.stop() is safe to call even if not running
     148          592 :     io_context_.stop();
     149              :     
     150          592 :     LOG_DEBUG("Standalone HTTP server stopped");
     151          592 :     return true;
     152              : }
     153              : 
     154              : } // namespace thinger::http
        

Generated by: LCOV version 2.0-1