From f3e1d387fa6a5e256020e33626a44df8f4f0630e Mon Sep 17 00:00:00 2001 From: Janni Date: Thu, 15 May 2025 10:36:26 +0200 Subject: [PATCH] Log invalid port (fixes #952) --- include/crow/http_server.h | 56 ++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/include/crow/http_server.h b/include/crow/http_server.h index 12ff3726d5..96c5801247 100644 --- a/include/crow/http_server.h +++ b/include/crow/http_server.h @@ -49,7 +49,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" uint16_t concurrency = 1, uint8_t timeout = 5, typename Adaptor::context* adaptor_ctx = nullptr): - acceptor_(io_context_,endpoint), + acceptor_(io_context_), signals_(io_context_), tick_timer_(io_context_), handler_(handler), @@ -59,7 +59,45 @@ namespace crow // NOTE: Already documented in "crow/app.h" task_queue_length_pool_(concurrency_ - 1), middlewares_(middlewares), adaptor_ctx_(adaptor_ctx) - {} + { + if (startup_failed_) { + CROW_LOG_ERROR << "Startup failed; not running server."; + return; + } + + error_code ec; + + acceptor_.open(endpoint.protocol(), ec); + if (ec) { + CROW_LOG_ERROR << "Failed to open acceptor: " << ec.message(); + startup_failed_ = true; + return; + } + + acceptor_.set_option(tcp::acceptor::reuse_address(true), ec); + if (ec) { + CROW_LOG_ERROR << "Failed to set socket option: " << ec.message(); + startup_failed_ = true; + return; + } + + acceptor_.bind(endpoint, ec); + if (ec) { + CROW_LOG_ERROR << "Failed to bind to " << endpoint.address().to_string() + << ":" << endpoint.port() << " - " << ec.message(); + startup_failed_ = true; + return; + } + + acceptor_.listen(tcp::acceptor::max_listen_connections, ec); + if (ec) { + CROW_LOG_ERROR << "Failed to listen on port: " << ec.message(); + startup_failed_ = true; + return; + } + + + } void set_tick_function(std::chrono::milliseconds d, std::function f) { @@ -80,6 +118,12 @@ namespace crow // NOTE: Already documented in "crow/app.h" void run() { + + if (startup_failed_) { + CROW_LOG_ERROR << "Server startup failed. Aborting run()."; + return; + } + uint16_t worker_thread_count = concurrency_ - 1; for (int i = 0; i < worker_thread_count; i++) io_context_pool_.emplace_back(new asio::io_context()); @@ -205,13 +249,14 @@ namespace crow // NOTE: Already documented in "crow/app.h" std::cv_status wait_for_start(std::chrono::steady_clock::time_point wait_until) { std::unique_lock lock(start_mutex_); - + std::cv_status status = std::cv_status::no_timeout; - while (!server_started_ && ( status==std::cv_status::no_timeout )) - status = cv_started_.wait_until(lock,wait_until); + while (!server_started_ && !startup_failed_ && status == std::cv_status::no_timeout) + status = cv_started_.wait_until(lock, wait_until); return status; } + void signal_clear() { signals_.clear(); @@ -288,6 +333,7 @@ namespace crow // NOTE: Already documented in "crow/app.h" tcp::acceptor acceptor_; bool shutting_down_ = false; bool server_started_{false}; + bool startup_failed_ = false; std::condition_variable cv_started_; std::mutex start_mutex_; asio::signal_set signals_;