use std::{net::SocketAddr, sync::Arc}; use axum::Router; use axum_server::{bind_rustls, tls_rustls::RustlsConfig, Handle as ServerHandle}; #[cfg(feature = "axum_dual_protocol")] use axum_server_dual_protocol::ServerExt; use conduit::{Result, Server}; use tokio::task::JoinSet; use tracing::{debug, info, warn}; pub(super) async fn serve( server: &Arc, app: Router, handle: ServerHandle, addrs: Vec, ) -> Result<()> { let config = &server.config; let tls = config.tls.as_ref().expect("TLS configuration"); debug!( "Using direct TLS. Certificate path {} and certificate private key path {}", &tls.certs, &tls.key ); info!( "Note: It is strongly recommended that you use a reverse proxy instead of running conduwuit directly with TLS." ); let conf = RustlsConfig::from_pem_file(&tls.certs, &tls.key).await?; if cfg!(feature = "axum_dual_protocol") { info!( "conduwuit was built with axum_dual_protocol feature to listen on both HTTP and HTTPS. This will only \ take effect if `dual_protocol` is enabled in `[global.tls]`" ); } let mut join_set = JoinSet::new(); let app = app.into_make_service_with_connect_info::(); if cfg!(feature = "axum_dual_protocol") && tls.dual_protocol { #[cfg(feature = "axum_dual_protocol")] for addr in &addrs { join_set.spawn_on( axum_server_dual_protocol::bind_dual_protocol(*addr, conf.clone()) .set_upgrade(false) .handle(handle.clone()) .serve(app.clone()), server.runtime(), ); } } else { for addr in &addrs { join_set.spawn_on( bind_rustls(*addr, conf.clone()) .handle(handle.clone()) .serve(app.clone()), server.runtime(), ); } } if cfg!(feature = "axum_dual_protocol") && tls.dual_protocol { warn!( "Listening on {:?} with TLS certificate {} and supporting plain text (HTTP) connections too (insecure!)", addrs, &tls.certs ); } else { info!("Listening on {:?} with TLS certificate {}", addrs, &tls.certs); } while join_set.join_next().await.is_some() {} Ok(()) }