v0.25.3
This commit is contained in:
1 parent
174389e5b1
commit
e6604e41fc
73 files changed
+1240
-201
No files matched your search
@@ -45,6 +45,59 @@ impl Default for ProxyTimeouts {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MethodPolicyMode {
|
||||
#[default]
|
||||
Off,
|
||||
Allow,
|
||||
Block,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct MethodPolicy {
|
||||
pub mode: MethodPolicyMode,
|
||||
pub methods: Vec<String>,
|
||||
}
|
||||
impl MethodPolicy {
|
||||
pub fn validate(&mut self) -> Result<()> {
|
||||
ensure!(self.methods.len() <= 32, "method policy allows at most 32 methods");
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
for method in &mut self.methods {
|
||||
*method = method.trim().to_ascii_uppercase();
|
||||
ensure!(
|
||||
!method.is_empty() && method.len() <= 32 && method.parse::<http::Method>().is_ok(),
|
||||
"invalid HTTP method in method policy"
|
||||
);
|
||||
ensure!(seen.insert(method.clone()), "duplicate HTTP method in method policy");
|
||||
}
|
||||
ensure!(
|
||||
self.mode == MethodPolicyMode::Off || !self.methods.is_empty(),
|
||||
"method allow/block policy requires at least one method"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn allows(&self, method: &http::Method) -> bool {
|
||||
let listed = self
|
||||
.methods
|
||||
.iter()
|
||||
.any(|candidate| candidate.eq_ignore_ascii_case(method.as_str()));
|
||||
match self.mode {
|
||||
MethodPolicyMode::Off => true,
|
||||
MethodPolicyMode::Allow => listed,
|
||||
MethodPolicyMode::Block => !listed,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allow_header(&self) -> Option<http::HeaderValue> {
|
||||
(self.mode == MethodPolicyMode::Allow)
|
||||
.then(|| self.methods.join(", ").parse::<http::HeaderValue>().ok())
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
impl ProxyTimeouts {
|
||||
pub fn validate(&self) -> Result<()> {
|
||||
for (name, value, max) in [
|
||||
@@ -204,6 +257,9 @@ pub struct Vhost {
|
||||
pub backend_timing_header: bool,
|
||||
#[serde(default)]
|
||||
pub rate_limit: crate::rate_limit::Settings,
|
||||
/// Optional allow/block policy for HTTP methods. Vhost and location policies stack.
|
||||
#[serde(default)]
|
||||
pub method_policy: MethodPolicy,
|
||||
#[serde(default)]
|
||||
pub basic_auth: crate::basic_auth::Settings,
|
||||
pub id: String,
|
||||
@@ -403,8 +459,17 @@ pub struct PathRoute {
|
||||
pub enabled: bool,
|
||||
#[serde(default)]
|
||||
pub cache: Option<bool>,
|
||||
/// Optional reusable ACL profile applied in addition to vhost policy.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub acl_profile_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub acl: Option<Acl>,
|
||||
/// Location-scoped country allow/block policy, stacked with vhost/profile policy.
|
||||
#[serde(default)]
|
||||
pub country_access: crate::rate_limit::CountryAccess,
|
||||
/// Location-scoped HTTP method allow/block policy, stacked with vhost policy.
|
||||
#[serde(default)]
|
||||
pub method_policy: MethodPolicy,
|
||||
#[serde(default)]
|
||||
pub headers: HeaderRules,
|
||||
/// Optional origin-path transformation. Query parameters are preserved.
|
||||
|
||||
Reference in new issue
Block a user