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.
This commit is contained in:
@@ -33,7 +33,7 @@ pub fn default_shutdown_timeout_secs() -> u64 {
|
|||||||
pub struct ListenerConfig {
|
pub struct ListenerConfig {
|
||||||
pub bind_addr: String,
|
pub bind_addr: String,
|
||||||
#[serde(default = "default_http_port")]
|
#[serde(default = "default_http_port")]
|
||||||
pub http_port: u16,
|
pub http_port: u32,
|
||||||
#[serde(default = "default_https_port")]
|
#[serde(default = "default_https_port")]
|
||||||
pub https_port: u16,
|
pub https_port: u16,
|
||||||
pub tls: TlsConfig,
|
pub tls: TlsConfig,
|
||||||
@@ -42,7 +42,7 @@ pub struct ListenerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn default_http_port() -> u16 {
|
fn default_http_port() -> u32 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,19 +41,19 @@ pub enum ValidationError {
|
|||||||
#[error("body.limit_bytes must be > 0, got {value}")]
|
#[error("body.limit_bytes must be > 0, got {value}")]
|
||||||
BodyLimitBytesZero { value: u64 },
|
BodyLimitBytesZero { value: u64 },
|
||||||
#[error("duplicate bind_addr:http_port combination: {bind_addr}:{http_port}")]
|
#[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(
|
#[error(
|
||||||
"listener {bind_addr}: http_port ({http_port}) and https_port ({https_port}) must differ"
|
"listener {bind_addr}: http_port ({http_port}) and https_port ({https_port}) must differ"
|
||||||
)]
|
)]
|
||||||
HttpsAndHttpPortSame {
|
HttpsAndHttpPortSame {
|
||||||
bind_addr: String,
|
bind_addr: String,
|
||||||
http_port: u16,
|
http_port: u32,
|
||||||
https_port: u16,
|
https_port: u16,
|
||||||
},
|
},
|
||||||
#[error("listener {bind_addr}: https_port must be 1-65535, got {https_port}")]
|
#[error("listener {bind_addr}: https_port must be 1-65535, got {https_port}")]
|
||||||
HttpsPortInvalid { bind_addr: String, https_port: u16 },
|
HttpsPortInvalid { bind_addr: String, https_port: u16 },
|
||||||
#[error("listener {bind_addr}: http_port must be 0 (disabled) or 1-65535, got {http_port}")]
|
#[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}")]
|
#[error("health_check_port {health_check_port} conflicts with listener {bind_addr}:{port}")]
|
||||||
HealthCheckPortConflict {
|
HealthCheckPortConflict {
|
||||||
health_check_port: u16,
|
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 {
|
errors.push(ValidationError::HttpsAndHttpPortSame {
|
||||||
bind_addr: listener.bind_addr.clone(),
|
bind_addr: listener.bind_addr.clone(),
|
||||||
http_port: listener.http_port,
|
http_port: listener.http_port,
|
||||||
@@ -175,11 +182,14 @@ pub fn validate(
|
|||||||
port: listener.https_port,
|
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 {
|
errors.push(ValidationError::HealthCheckPortConflict {
|
||||||
health_check_port: static_config.health_check_port,
|
health_check_port: static_config.health_check_port,
|
||||||
bind_addr: listener.bind_addr.clone(),
|
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 { .. })));
|
.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]
|
#[test]
|
||||||
fn rule13_http_port_disabled_valid() {
|
fn rule13_http_port_disabled_valid() {
|
||||||
let mut config = valid_static_config();
|
let mut config = valid_static_config();
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ async fn test_rate_limit_eviction_task() {
|
|||||||
|
|
||||||
fn make_redirect_listener_config(
|
fn make_redirect_listener_config(
|
||||||
bind_addr: &str,
|
bind_addr: &str,
|
||||||
http_port: u16,
|
http_port: u32,
|
||||||
https_port: u16,
|
https_port: u16,
|
||||||
) -> reverse_proxy::config::static_config::ListenerConfig {
|
) -> reverse_proxy::config::static_config::ListenerConfig {
|
||||||
reverse_proxy::config::static_config::ListenerConfig {
|
reverse_proxy::config::static_config::ListenerConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user