feat: add HTTPS/TLS server support via rustls
Add optional TLS support for the server using axum-server with the tls-rustls feature. When --server-cert and --server-key are provided (and tls feature is enabled), the server binds with TLS instead of plain HTTP. Changes: - Add axum-server dependency with optional tls-rustls feature - New 'tls' feature flag (independent of 'server') - --server-cert/--server-key CLI args gated behind tls feature - ServerConfig extended with cert_file/key_file fields - Conditional TLS/HTTP binding in server mod.rs - Fix PathBuf::to_str().unwrap() panic risk -> to_string_lossy() - Update README.md and DESIGN.md with TLS documentation
This commit is contained in:
@@ -67,6 +67,14 @@ pub struct ServerConfig {
|
||||
/// Pre-hashed password (Unix crypt format) for secure authentication. Preferred
|
||||
/// over plain text password for production use.
|
||||
pub password_hash: Option<String>,
|
||||
/// Optional path to TLS certificate file (PEM).
|
||||
///
|
||||
/// When both cert_file and key_file are set, the server uses HTTPS.
|
||||
pub cert_file: Option<PathBuf>,
|
||||
/// Optional path to TLS private key file (PEM).
|
||||
///
|
||||
/// When both cert_file and key_file are set, the server uses HTTPS.
|
||||
pub key_file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Application state shared across all routes.
|
||||
|
||||
@@ -52,6 +52,8 @@ pub fn mode_server(
|
||||
port: Some(server_port),
|
||||
password: settings.server_password(),
|
||||
password_hash: settings.server_password_hash(),
|
||||
cert_file: settings.server_cert_file(),
|
||||
key_file: settings.server_key_file(),
|
||||
};
|
||||
|
||||
// Create ItemService once
|
||||
@@ -138,14 +140,31 @@ async fn run_server(
|
||||
|
||||
let addr: SocketAddr = bind_address.parse()?;
|
||||
|
||||
// Build the app into a service
|
||||
let service = app.into_make_service_with_connect_info::<SocketAddr>();
|
||||
|
||||
// Use TLS if both cert and key files are provided
|
||||
#[cfg(feature = "tls")]
|
||||
if let (Some(cert_file), Some(key_file)) = (&config.cert_file, &config.key_file) {
|
||||
info!("SERVER: HTTPS server listening on {addr}");
|
||||
|
||||
use axum_server::tls_rustls::RustlsConfig;
|
||||
|
||||
let tls_config = RustlsConfig::from_pem_file(cert_file, key_file)
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to load TLS config: {e}"))?;
|
||||
|
||||
axum_server::bind_rustls(addr, tls_config)
|
||||
.serve(service)
|
||||
.await?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
info!("SERVER: HTTP server listening on {addr}");
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(addr).await?;
|
||||
axum::serve(
|
||||
listener,
|
||||
app.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
)
|
||||
.await?;
|
||||
axum::serve(listener, service).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user