use axum_client_ip::SecureClientIpSource; use serde::Deserialize; use std::net::SocketAddr; use std::num::NonZeroU32; mod dns; pub use crate::config::dns::{DnsConfig, DnsResolverConfig}; #[derive(Deserialize, Default, Clone)] pub struct EchoIpServiceConfig { pub server: ServerConfig, pub dns: DnsConfig, pub geoip: GeoIpConfig, pub template: TemplateConfig, pub ratelimit: RatelimitConfig, } #[derive(Deserialize, Clone)] pub struct ServerConfig { pub listen_on: SocketAddr, pub ip_header: SecureClientIpSource, pub allow_private_ip_lookup: bool, } #[derive(Deserialize, Clone)] pub struct GeoIpConfig { pub asn_database: Option, pub location_database: Option, } #[derive(Deserialize, Clone)] pub struct TemplateConfig { pub template_location: String, pub extra_config: Option, pub text_user_agents: Vec, } #[derive(Deserialize, Clone)] pub struct RatelimitConfig { pub per_minute: NonZeroU32, pub burst: NonZeroU32, } impl Default for ServerConfig { fn default() -> Self { ServerConfig { listen_on: "127.0.0.1:3000".parse().unwrap(), ip_header: SecureClientIpSource::ConnectInfo, allow_private_ip_lookup: false, } } } impl Default for GeoIpConfig { fn default() -> Self { GeoIpConfig { asn_database: Some("mmdb/GeoLite2-ASN.mmdb".to_string()), location_database: Some("mmdb/GeoLite2-City.mmdb".to_string()), } } } impl Default for TemplateConfig { fn default() -> Self { TemplateConfig { template_location: "templates/".to_string(), extra_config: None, text_user_agents: vec!["curl/".to_string()], } } } impl Default for RatelimitConfig { fn default() -> Self { RatelimitConfig { per_minute: NonZeroU32::new(20).unwrap(), burst: NonZeroU32::new(15).unwrap(), } } }