104 lines
2.8 KiB
Rust
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);
|
|
}
|
|
}
|