| 17 | } |
| 18 | |
| 19 | bool createServer( |
| 20 | const Poco::Util::AbstractConfiguration & config, |
| 21 | const std::string & listen_host, |
| 22 | const char * port_name, |
| 23 | bool listen_try, |
| 24 | bool start_server, |
| 25 | std::vector<ProtocolServerAdapter> & servers, |
| 26 | CreateServerFunc && func, |
| 27 | LoggerRawPtr log) |
| 28 | { |
| 29 | /// For testing purposes, user may omit tcp_port or http_port or https_port in configuration file. |
| 30 | if (config.getString(port_name, "").empty()) |
| 31 | return false; |
| 32 | |
| 33 | /// If we already have an active server for this listen_host/port_name, don't create it again. |
| 34 | for (const auto & server : servers) |
| 35 | { |
| 36 | if (!server.isStopping() && server.getListenHost() == listen_host && server.getPortName() == port_name) |
| 37 | return false; |
| 38 | } |
| 39 | |
| 40 | auto port = config.getInt(port_name); |
| 41 | try |
| 42 | { |
| 43 | servers.push_back(func(static_cast<UInt16>(port))); |
| 44 | try |
| 45 | { |
| 46 | if (start_server) |
| 47 | { |
| 48 | servers.back().start(); |
| 49 | LOG_INFO(log, "Listening for {}", servers.back().getDescription()); |
| 50 | } |
| 51 | return true; |
| 52 | } |
| 53 | catch (...) |
| 54 | { |
| 55 | /// Roll back the just-pushed adapter so its bound socket is released |
| 56 | /// and a half-initialized listener does not linger in `servers`. We must |
| 57 | /// catch all exception types — not only `Poco::Exception` — so the outer |
| 58 | /// `Poco::Exception` handler below still wraps `Poco`-class errors into |
| 59 | /// `NETWORK_ERROR` (or logs them when `listen_try`) while non-`Poco` |
| 60 | /// exceptions propagate to the caller after the rollback. |
| 61 | servers.pop_back(); |
| 62 | throw; |
| 63 | } |
| 64 | } |
| 65 | catch (const Poco::Exception &) |
| 66 | { |
| 67 | if (listen_try) |
| 68 | { |
| 69 | LOG_WARNING(log, "Listen [{}]:{} failed: {}. If it is an IPv6 or IPv4 address and your host has disabled IPv6 or IPv4, " |
| 70 | "then consider to " |
| 71 | "specify not disabled IPv4 or IPv6 address to listen in <listen_host> element of configuration " |
| 72 | "file. Example for disabled IPv6: <listen_host>0.0.0.0</listen_host> ." |
| 73 | " Example for disabled IPv4: <listen_host>::</listen_host>", |
| 74 | listen_host, port, getCurrentExceptionMessage(false)); |
| 75 | } |
| 76 | else |
no test coverage detected