Files
NxMesh/apps/nxmesh-master/src/config/settings/server.rs

104 lines
2.8 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::config::settings::{
Validate, ValidationError, cert::CertificateSettings, cors::CorsSettings,
};
/// HTTP server settings
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerSettings {
#[serde(default = "default_server_bind_address")]
pub bind_address: String,
#[serde(default = "default_server_port")]
pub port: u16,
#[serde(default)]
pub certificate: CertificateSettings,
#[serde(default)]
pub cors: Option<CorsSettings>,
}
impl Validate for ServerSettings {
fn validate(&self) -> Result<(), ValidationError> {
if self.bind_address.is_empty() {
return Err("Server bind address cannot be empty".into());
}
if self.port == 0 {
return Err("Server port must be greater than 0".into());
}
self.certificate.validate()?;
if let Some(cors) = &self.cors {
cors.validate()?;
}
Ok(())
}
}
fn default_server_bind_address() -> String {
"0.0.0.0".into()
}
fn default_server_port() -> u16 {
8080
}
#[cfg(test)]
mod tests {
use std::{
fs,
path::PathBuf,
time::{SystemTime, UNIX_EPOCH},
};
use rcgen::string::Ia5String;
use super::*;
#[test]
fn test_esnure_send_and_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<ServerSettings>();
}
fn make_temp_dir(prefix: &str) -> PathBuf {
let ts = SystemTime::now().duration_since(UNIX_EPOCH);
assert!(ts.is_ok());
let ts = ts.unwrap_or_default();
let path = std::env::temp_dir().join(format!(
"{}_{}_{}",
prefix,
std::process::id(),
ts.as_nanos()
));
let created = fs::create_dir_all(&path);
assert!(created.is_ok());
path
}
#[test]
fn server_validate_fails_for_zero_port() {
let cert_dir = make_temp_dir("nxmesh-master-server-validate");
let san = Ia5String::try_from("localhost".to_string());
assert!(san.is_ok());
let san = san.unwrap_or_else(|_| unreachable!());
let server = ServerSettings {
bind_address: "0.0.0.0".to_string(),
port: 0,
certificate: CertificateSettings {
cert_dir: cert_dir.to_string_lossy().to_string(),
san_dns: vec![san],
san_ip: Vec::new(),
cert_path: None,
key_path: None,
},
cors: None,
};
let result = server.validate();
assert!(result.is_err());
let msg = result.err().unwrap_or_default();
assert!(msg.contains("Server port must be greater than 0"));
let _ = fs::remove_dir_all(&cert_dir);
}
}