| 234 | } |
| 235 | |
| 236 | bool wait_for_ui_ready() { |
| 237 | std::cout << "Waiting for Web UI to be ready..."; |
| 238 | |
| 239 | // Wait up to 30 seconds for the web UI to start |
| 240 | for (int i = 0; i < 30; i++) { |
| 241 | PMIB_TCPTABLE tcp_table = nullptr; |
| 242 | ULONG table_size = 0; |
| 243 | ULONG err; |
| 244 | |
| 245 | auto fg = util::fail_guard([&tcp_table]() { |
| 246 | free(tcp_table); |
| 247 | }); |
| 248 | |
| 249 | do { |
| 250 | // Query all open TCP sockets to look for our web UI port |
| 251 | err = GetTcpTable(tcp_table, &table_size, false); |
| 252 | if (err == ERROR_INSUFFICIENT_BUFFER) { |
| 253 | free(tcp_table); |
| 254 | tcp_table = (PMIB_TCPTABLE) malloc(table_size); |
| 255 | } |
| 256 | } while (err == ERROR_INSUFFICIENT_BUFFER); |
| 257 | |
| 258 | if (err != NO_ERROR) { |
| 259 | BOOST_LOG(error) << "Failed to query TCP table: "sv << err; |
| 260 | return false; |
| 261 | } |
| 262 | |
| 263 | uint16_t port_nbo = htons(net::map_port(confighttp::PORT_HTTPS)); |
| 264 | for (DWORD i = 0; i < tcp_table->dwNumEntries; i++) { |
| 265 | auto &entry = tcp_table->table[i]; |
| 266 | |
| 267 | // Look for our port in the listening state |
| 268 | if (entry.dwLocalPort == port_nbo && entry.dwState == MIB_TCP_STATE_LISTEN) { |
| 269 | std::cout << std::endl; |
| 270 | return true; |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | Sleep(1000); |
| 275 | std::cout << '.'; |
| 276 | } |
| 277 | |
| 278 | std::cout << "timed out"sv << std::endl; |
| 279 | return false; |
| 280 | } |
| 281 | } // namespace service_ctrl |
| 282 | #endif |
no test coverage detected