Start the HTTP API server (plain HTTP or HTTPS). If `tls_settings` is provided, serves HTTPS via axum-server + rustls. Otherwise serves plain HTTP via axum::serve.
(
listen: SocketAddr,
shared: Arc<SharedState>,
auth_mode: AuthMode,
tls_settings: Option<&crate::config::server::TlsSettings>,
bus: crate::control::shutdown::ShutdownBus,
)
| 265 | /// If `tls_settings` is provided, serves HTTPS via axum-server + rustls. |
| 266 | /// Otherwise serves plain HTTP via axum::serve. |
| 267 | pub async fn run( |
| 268 | listen: SocketAddr, |
| 269 | shared: Arc<SharedState>, |
| 270 | auth_mode: AuthMode, |
| 271 | tls_settings: Option<&crate::config::server::TlsSettings>, |
| 272 | bus: crate::control::shutdown::ShutdownBus, |
| 273 | ) -> crate::Result<()> { |
| 274 | let drain_guard = bus.register_task( |
| 275 | crate::control::shutdown::ShutdownPhase::DrainingListeners, |
| 276 | "http", |
| 277 | None, |
| 278 | ); |
| 279 | let mut shutdown_rx = bus.handle().flat_watch().raw_receiver(); |
| 280 | |
| 281 | let query_ctx = Arc::new(crate::control::planner::context::QueryContext::for_state( |
| 282 | &shared, |
| 283 | )); |
| 284 | let state = AppState { |
| 285 | shared, |
| 286 | auth_mode, |
| 287 | query_ctx, |
| 288 | }; |
| 289 | let router = build_router(state); |
| 290 | |
| 291 | if let Some(tls) = tls_settings { |
| 292 | // HTTPS via axum-server + rustls. |
| 293 | let rustls_config = |
| 294 | axum_server::tls_rustls::RustlsConfig::from_pem_file(&tls.cert_path, &tls.key_path) |
| 295 | .await |
| 296 | .map_err(|e| crate::Error::Config { |
| 297 | detail: format!("HTTP TLS config error: {e}"), |
| 298 | })?; |
| 299 | |
| 300 | info!(%listen, tls = true, "HTTPS API server listening"); |
| 301 | |
| 302 | let handle = axum_server::Handle::new(); |
| 303 | let shutdown_handle = handle.clone(); |
| 304 | tokio::spawn(async move { |
| 305 | let _ = shutdown_rx.changed().await; |
| 306 | shutdown_handle.graceful_shutdown(Some(std::time::Duration::from_secs(5))); |
| 307 | }); |
| 308 | |
| 309 | axum_server::bind_rustls(listen, rustls_config) |
| 310 | .handle(handle) |
| 311 | .serve(router.into_make_service_with_connect_info::<std::net::SocketAddr>()) |
| 312 | .await |
| 313 | .map_err(crate::Error::Io)?; |
| 314 | } else { |
| 315 | // Plain HTTP. |
| 316 | let listener = tokio::net::TcpListener::bind(listen).await?; |
| 317 | let local_addr = listener.local_addr()?; |
| 318 | info!(%local_addr, "HTTP API server listening"); |
| 319 | |
| 320 | axum::serve( |
| 321 | listener, |
| 322 | router.into_make_service_with_connect_info::<std::net::SocketAddr>(), |
| 323 | ) |
| 324 | .with_graceful_shutdown(async move { |
nothing calls this directly
no test coverage detected