From d24148dae973ef97e10447586e2904952dc90702 Mon Sep 17 00:00:00 2001 From: "glm-5.1" Date: Fri, 12 Jun 2026 04:28:35 +0000 Subject: [PATCH] Add http_port range validation (0 or 1-65535) Change http_port type from u16 to u32 to allow out-of-range values to be caught by validation. Add HttpPortInvalid error variant and validation check for http_port > 65535. Add test for http_port=65536 producing HttpPortInvalid. http_port=0 (disabled) remains valid per existing test. --- src/config/static_config.rs | 4 ++-- src/config/validation.rs | 36 ++++++++++++++++++++++++++++++------ tests/integration_test.rs | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/config/static_config.rs b/src/config/static_config.rs index 58e9bb8..9d7c251 100644 --- a/src/config/static_config.rs +++ b/src/config/static_config.rs @@ -33,7 +33,7 @@ pub fn default_shutdown_timeout_secs() -> u64 { pub struct ListenerConfig { pub bind_addr: String, #[serde(default = "default_http_port")] - pub http_port: u16, + pub http_port: u32, #[serde(default = "default_https_port")] pub https_port: u16, pub tls: TlsConfig, @@ -42,7 +42,7 @@ pub struct ListenerConfig { } #[allow(dead_code)] -fn default_http_port() -> u16 { +fn default_http_port() -> u32 { 80 } diff --git a/src/config/validation.rs b/src/config/validation.rs index fbe44e2..8ec44d8 100644 --- a/src/config/validation.rs +++ b/src/config/validation.rs @@ -41,19 +41,19 @@ pub enum ValidationError { #[error("body.limit_bytes must be > 0, got {value}")] BodyLimitBytesZero { value: u64 }, #[error("duplicate bind_addr:http_port combination: {bind_addr}:{http_port}")] - DuplicateHttpBind { bind_addr: String, http_port: u16 }, + DuplicateHttpBind { bind_addr: String, http_port: u32 }, #[error( "listener {bind_addr}: http_port ({http_port}) and https_port ({https_port}) must differ" )] HttpsAndHttpPortSame { bind_addr: String, - http_port: u16, + http_port: u32, https_port: u16, }, #[error("listener {bind_addr}: https_port must be 1-65535, got {https_port}")] HttpsPortInvalid { bind_addr: String, https_port: u16 }, #[error("listener {bind_addr}: http_port must be 0 (disabled) or 1-65535, got {http_port}")] - HttpPortInvalid { bind_addr: String, http_port: u16 }, + HttpPortInvalid { bind_addr: String, http_port: u32 }, #[error("health_check_port {health_check_port} conflicts with listener {bind_addr}:{port}")] HealthCheckPortConflict { health_check_port: u16, @@ -120,7 +120,14 @@ pub fn validate( }); } - if listener.http_port > 0 && listener.http_port == listener.https_port { + if listener.http_port > 65535 { + errors.push(ValidationError::HttpPortInvalid { + bind_addr: listener.bind_addr.clone(), + http_port: listener.http_port, + }); + } + + if listener.http_port > 0 && listener.http_port == listener.https_port as u32 { errors.push(ValidationError::HttpsAndHttpPortSame { bind_addr: listener.bind_addr.clone(), http_port: listener.http_port, @@ -175,11 +182,14 @@ pub fn validate( port: listener.https_port, }); } - if listener.http_port > 0 && static_config.health_check_port == listener.http_port { + if listener.http_port > 0 + && listener.http_port <= 65535 + && static_config.health_check_port as u32 == listener.http_port + { errors.push(ValidationError::HealthCheckPortConflict { health_check_port: static_config.health_check_port, bind_addr: listener.bind_addr.clone(), - port: listener.http_port, + port: listener.http_port as u16, }); } } @@ -710,6 +720,20 @@ mod tests { .any(|e| matches!(e, ValidationError::HttpsPortInvalid { .. }))); } + #[test] + fn rule13_http_port_invalid() { + let mut config = valid_static_config(); + config.listeners[0].http_port = 65536; + config.listeners[0].tls = make_acme_tls(); + let dynamic = valid_dynamic_config(); + let result = validate(&config, &dynamic, false); + assert!(result.is_err()); + let errors = result.unwrap_err(); + assert!(errors + .iter() + .any(|e| matches!(e, ValidationError::HttpPortInvalid { .. }))); + } + #[test] fn rule13_http_port_disabled_valid() { let mut config = valid_static_config(); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 021d805..b677853 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -259,7 +259,7 @@ async fn test_rate_limit_eviction_task() { fn make_redirect_listener_config( bind_addr: &str, - http_port: u16, + http_port: u32, https_port: u16, ) -> reverse_proxy::config::static_config::ListenerConfig { reverse_proxy::config::static_config::ListenerConfig {