http_acl/
acl.rs

1//! Contains the [`HttpAcl`], [`HttpAclBuilder`],
2//! and related types.
3
4#[cfg(feature = "hashbrown")]
5use hashbrown::{HashMap, HashSet, hash_map::Entry};
6#[cfg(not(feature = "hashbrown"))]
7use std::collections::{HashMap, HashSet, hash_map::Entry};
8use std::hash::Hash;
9use std::net::{IpAddr, SocketAddr};
10use std::ops::RangeInclusive;
11use std::sync::Arc;
12
13use matchit::Router;
14#[cfg(feature = "serde")]
15use serde::{Deserialize, Serialize};
16
17use crate::{
18    error::AddError,
19    utils::{self, IntoIpRange, authority::Authority},
20};
21
22/// A function that validates an HTTP request against an ACL.
23pub type ValidateFn = Arc<
24    dyn for<'h> Fn(
25            &str,
26            &Authority,
27            Box<dyn Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h>,
28            Option<&[u8]>,
29        ) -> AclClassification
30        + Send
31        + Sync,
32>;
33
34#[derive(Clone)]
35/// Represents an HTTP ACL.
36pub struct HttpAcl {
37    allow_http: bool,
38    allow_https: bool,
39    allowed_methods: HashSet<HttpRequestMethod>,
40    denied_methods: HashSet<HttpRequestMethod>,
41    allowed_hosts: HashSet<Box<str>>,
42    denied_hosts: HashSet<Box<str>>,
43    allowed_port_ranges: Box<[RangeInclusive<u16>]>,
44    denied_port_ranges: Box<[RangeInclusive<u16>]>,
45    allowed_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
46    denied_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
47    static_dns_mapping: HashMap<Box<str>, SocketAddr>,
48    allowed_headers: HashMap<Box<str>, Option<Box<str>>>,
49    denied_headers: HashMap<Box<str>, Option<Box<str>>>,
50    allowed_url_paths_router: Router<()>,
51    denied_url_paths_router: Router<()>,
52    validate_fn: Option<ValidateFn>,
53    allow_private_ip_ranges: bool,
54    method_acl_default: bool,
55    host_acl_default: bool,
56    port_acl_default: bool,
57    ip_acl_default: bool,
58    header_acl_default: bool,
59    url_path_acl_default: bool,
60}
61
62impl std::fmt::Debug for HttpAcl {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        f.debug_struct("HttpAcl")
65            .field("allow_http", &self.allow_http)
66            .field("allow_https", &self.allow_https)
67            .field("allowed_methods", &self.allowed_methods)
68            .field("denied_methods", &self.denied_methods)
69            .field("allowed_hosts", &self.allowed_hosts)
70            .field("denied_hosts", &self.denied_hosts)
71            .field("allowed_port_ranges", &self.allowed_port_ranges)
72            .field("denied_port_ranges", &self.denied_port_ranges)
73            .field("allowed_ip_ranges", &self.allowed_ip_ranges)
74            .field("denied_ip_ranges", &self.denied_ip_ranges)
75            .field("static_dns_mapping", &self.static_dns_mapping)
76            .field("allowed_headers", &self.allowed_headers)
77            .field("denied_headers", &self.denied_headers)
78            .field("allow_private_ip_ranges", &self.allow_private_ip_ranges)
79            .field("method_acl_default", &self.method_acl_default)
80            .field("host_acl_default", &self.host_acl_default)
81            .field("port_acl_default", &self.port_acl_default)
82            .field("ip_acl_default", &self.ip_acl_default)
83            .field("header_acl_default", &self.header_acl_default)
84            .field("url_path_acl_default", &self.url_path_acl_default)
85            .finish()
86    }
87}
88
89impl PartialEq for HttpAcl {
90    fn eq(&self, other: &Self) -> bool {
91        self.allow_http == other.allow_http
92            && self.allow_https == other.allow_https
93            && self.allowed_methods == other.allowed_methods
94            && self.denied_methods == other.denied_methods
95            && self.allowed_hosts == other.allowed_hosts
96            && self.denied_hosts == other.denied_hosts
97            && self.allowed_port_ranges == other.allowed_port_ranges
98            && self.denied_port_ranges == other.denied_port_ranges
99            && self.allowed_ip_ranges == other.allowed_ip_ranges
100            && self.denied_ip_ranges == other.denied_ip_ranges
101            && self.static_dns_mapping == other.static_dns_mapping
102            && self.allowed_headers == other.allowed_headers
103            && self.denied_headers == other.denied_headers
104            && self.allow_private_ip_ranges == other.allow_private_ip_ranges
105            && self.method_acl_default == other.method_acl_default
106            && self.host_acl_default == other.host_acl_default
107            && self.port_acl_default == other.port_acl_default
108            && self.ip_acl_default == other.ip_acl_default
109            && self.header_acl_default == other.header_acl_default
110            && self.url_path_acl_default == other.url_path_acl_default
111    }
112}
113
114impl std::default::Default for HttpAcl {
115    fn default() -> Self {
116        Self {
117            allow_http: true,
118            allow_https: true,
119            allowed_methods: [
120                HttpRequestMethod::CONNECT,
121                HttpRequestMethod::DELETE,
122                HttpRequestMethod::GET,
123                HttpRequestMethod::HEAD,
124                HttpRequestMethod::OPTIONS,
125                HttpRequestMethod::PATCH,
126                HttpRequestMethod::POST,
127                HttpRequestMethod::PUT,
128                HttpRequestMethod::TRACE,
129            ]
130            .into_iter()
131            .collect(),
132            denied_methods: HashSet::new(),
133            allowed_hosts: HashSet::new(),
134            denied_hosts: HashSet::new(),
135            allowed_port_ranges: vec![80..=80, 443..=443].into_boxed_slice(),
136            denied_port_ranges: Vec::new().into_boxed_slice(),
137            allowed_ip_ranges: Vec::new().into_boxed_slice(),
138            denied_ip_ranges: Vec::new().into_boxed_slice(),
139            static_dns_mapping: HashMap::new(),
140            allowed_headers: HashMap::new(),
141            denied_headers: HashMap::new(),
142            allowed_url_paths_router: Router::new(),
143            denied_url_paths_router: Router::new(),
144            validate_fn: None,
145            allow_private_ip_ranges: false,
146            method_acl_default: false,
147            host_acl_default: false,
148            port_acl_default: false,
149            ip_acl_default: false,
150            header_acl_default: true,
151            url_path_acl_default: true,
152        }
153    }
154}
155
156impl HttpAcl {
157    /// Returns a new [`HttpAclBuilder`].
158    pub fn builder() -> HttpAclBuilder {
159        HttpAclBuilder::new()
160    }
161
162    /// Returns whether the scheme is allowed.
163    pub fn is_scheme_allowed(&self, scheme: &str) -> AclClassification {
164        if scheme == "http" && self.allow_http || scheme == "https" && self.allow_https {
165            AclClassification::AllowedUserAcl
166        } else {
167            AclClassification::DeniedUserAcl
168        }
169    }
170
171    /// Returns whether the method is allowed.
172    pub fn is_method_allowed(&self, method: impl Into<HttpRequestMethod>) -> AclClassification {
173        let method = method.into();
174        if self.allowed_methods.contains(&method) {
175            AclClassification::AllowedUserAcl
176        } else if self.denied_methods.contains(&method) {
177            AclClassification::DeniedUserAcl
178        } else if self.method_acl_default {
179            AclClassification::AllowedDefault
180        } else {
181            AclClassification::DeniedDefault
182        }
183    }
184
185    /// Returns whether the host is allowed.
186    pub fn is_host_allowed(&self, host: &str) -> AclClassification {
187        if self.denied_hosts.iter().any(|h| h.as_ref() == host) {
188            AclClassification::DeniedUserAcl
189        } else if self.allowed_hosts.iter().any(|h| h.as_ref() == host) {
190            AclClassification::AllowedUserAcl
191        } else if self.host_acl_default {
192            AclClassification::AllowedDefault
193        } else {
194            AclClassification::DeniedDefault
195        }
196    }
197
198    /// Returns whether the port is allowed.
199    pub fn is_port_allowed(&self, port: u16) -> AclClassification {
200        if Self::is_port_in_ranges(port, &self.denied_port_ranges) {
201            AclClassification::DeniedUserAcl
202        } else if Self::is_port_in_ranges(port, &self.allowed_port_ranges) {
203            AclClassification::AllowedUserAcl
204        } else if self.port_acl_default {
205            AclClassification::AllowedDefault
206        } else {
207            AclClassification::DeniedDefault
208        }
209    }
210
211    /// Returns whether an IP is allowed.
212    pub fn is_ip_allowed(&self, ip: &IpAddr) -> AclClassification {
213        if (!utils::ip::is_global_ip(ip) || ip.is_loopback()) && !utils::ip::is_private_ip(ip) {
214            if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
215                return AclClassification::AllowedUserAcl;
216            } else {
217                return AclClassification::DeniedNotGlobal;
218            }
219        }
220
221        if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
222            AclClassification::AllowedUserAcl
223        } else if Self::is_ip_in_ranges(ip, &self.denied_ip_ranges) {
224            AclClassification::DeniedUserAcl
225        } else if utils::ip::is_private_ip(ip) && !self.allow_private_ip_ranges {
226            AclClassification::DeniedPrivateRange
227        } else if self.ip_acl_default {
228            AclClassification::AllowedDefault
229        } else {
230            AclClassification::DeniedDefault
231        }
232    }
233
234    /// Resolve static DNS mapping.
235    pub fn resolve_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
236        self.static_dns_mapping.get(host).copied()
237    }
238
239    /// Returns whether a header is allowed.
240    pub fn is_header_allowed(&self, header_name: &str, header_value: &str) -> AclClassification {
241        if let Some(allowed_value) = self.allowed_headers.get(header_name) {
242            if allowed_value.as_deref() == Some(header_value) || allowed_value.is_none() {
243                AclClassification::AllowedUserAcl
244            } else {
245                AclClassification::DeniedUserAcl
246            }
247        } else if let Some(denied_value) = self.denied_headers.get(header_name) {
248            if denied_value.as_deref() == Some(header_value) || denied_value.is_none() {
249                AclClassification::DeniedUserAcl
250            } else {
251                AclClassification::AllowedUserAcl
252            }
253        } else if self.header_acl_default {
254            AclClassification::AllowedDefault
255        } else {
256            AclClassification::DeniedDefault
257        }
258    }
259
260    /// Returns whether a URL path is allowed.
261    pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
262        if self.allowed_url_paths_router.at(url_path).is_ok() {
263            AclClassification::AllowedUserAcl
264        } else if self.denied_url_paths_router.at(url_path).is_ok() {
265            AclClassification::DeniedUserAcl
266        } else if self.url_path_acl_default {
267            AclClassification::AllowedDefault
268        } else {
269            AclClassification::DeniedDefault
270        }
271    }
272
273    /// Returns whether a request is valid.
274    pub fn is_valid<'h>(
275        &self,
276        scheme: &str,
277        authority: &Authority,
278        headers: impl Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h,
279        body: Option<&[u8]>,
280    ) -> AclClassification {
281        if let Some(validate_fn) = &self.validate_fn {
282            validate_fn(scheme, authority, Box::new(headers), body)
283        } else {
284            AclClassification::AllowedDefault
285        }
286    }
287
288    /// Checks if an ip is in a list of ip ranges.
289    fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
290        ranges.iter().any(|range| range.contains(ip))
291    }
292
293    /// Checks if a port is in a list of port ranges.
294    fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
295        ranges.iter().any(|range| range.contains(&port))
296    }
297}
298
299/// Represents an ACL Classification.
300#[non_exhaustive]
301#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
302pub enum AclClassification {
303    /// The entity is allowed according to the allowed ACL.
304    AllowedUserAcl,
305    /// The entity is allowed because the default is to allow if no ACL match is found.
306    AllowedDefault,
307    /// The entity is denied according to the denied ACL.
308    DeniedUserAcl,
309    /// The entity is denied because the default is to deny if no ACL match is found.
310    DeniedDefault,
311    /// The entity is denied.
312    Denied(String),
313    /// The IP is denied because it is not global.
314    DeniedNotGlobal,
315    /// The IP is denied because it is in a private range.
316    DeniedPrivateRange,
317}
318
319impl std::fmt::Display for AclClassification {
320    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321        match self {
322            AclClassification::AllowedUserAcl => {
323                write!(f, "The entity is allowed according to the allowed ACL.")
324            }
325            AclClassification::AllowedDefault => write!(
326                f,
327                "The entity is allowed because the default is to allow if no ACL match is found."
328            ),
329            AclClassification::DeniedUserAcl => {
330                write!(f, "The entity is denied according to the denied ACL.")
331            }
332            AclClassification::DeniedNotGlobal => {
333                write!(f, "The ip is denied because it is not global.")
334            }
335            AclClassification::DeniedPrivateRange => {
336                write!(f, "The ip is denied because it is in a private range.")
337            }
338            AclClassification::DeniedDefault => write!(
339                f,
340                "The entity is denied because the default is to deny if no ACL match is found."
341            ),
342            AclClassification::Denied(reason) => {
343                write!(f, "The entity is denied because {}.", reason)
344            }
345        }
346    }
347}
348
349impl AclClassification {
350    /// Returns whether the classification is allowed.
351    pub fn is_allowed(&self) -> bool {
352        matches!(
353            self,
354            AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
355        )
356    }
357
358    /// Returns whether the classification is denied.
359    pub fn is_denied(&self) -> bool {
360        matches!(
361            self,
362            AclClassification::DeniedUserAcl
363                | AclClassification::Denied(_)
364                | AclClassification::DeniedDefault
365                | AclClassification::DeniedNotGlobal
366                | AclClassification::DeniedPrivateRange
367        )
368    }
369}
370
371/// Represents an HTTP request method.
372#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
373#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
374pub enum HttpRequestMethod {
375    /// The CONNECT method.
376    CONNECT,
377    /// The DELETE method.
378    DELETE,
379    /// The GET method.
380    GET,
381    /// The HEAD method.
382    HEAD,
383    /// The OPTIONS method.
384    OPTIONS,
385    /// The PATCH method.
386    PATCH,
387    /// The POST method.
388    POST,
389    /// The PUT method.
390    PUT,
391    /// The TRACE method.
392    TRACE,
393    /// Any other method.
394    OTHER(Box<str>),
395}
396
397impl From<&str> for HttpRequestMethod {
398    fn from(method: &str) -> Self {
399        match method {
400            "CONNECT" => HttpRequestMethod::CONNECT,
401            "DELETE" => HttpRequestMethod::DELETE,
402            "GET" => HttpRequestMethod::GET,
403            "HEAD" => HttpRequestMethod::HEAD,
404            "OPTIONS" => HttpRequestMethod::OPTIONS,
405            "PATCH" => HttpRequestMethod::PATCH,
406            "POST" => HttpRequestMethod::POST,
407            "PUT" => HttpRequestMethod::PUT,
408            "TRACE" => HttpRequestMethod::TRACE,
409            _ => HttpRequestMethod::OTHER(method.into()),
410        }
411    }
412}
413
414impl HttpRequestMethod {
415    /// Return the method as a `&str`.
416    pub fn as_str(&self) -> &str {
417        match self {
418            HttpRequestMethod::CONNECT => "CONNECT",
419            HttpRequestMethod::DELETE => "DELETE",
420            HttpRequestMethod::GET => "GET",
421            HttpRequestMethod::HEAD => "HEAD",
422            HttpRequestMethod::OPTIONS => "OPTIONS",
423            HttpRequestMethod::PATCH => "PATCH",
424            HttpRequestMethod::POST => "POST",
425            HttpRequestMethod::PUT => "PUT",
426            HttpRequestMethod::TRACE => "TRACE",
427            HttpRequestMethod::OTHER(other) => other,
428        }
429    }
430}
431
432/// A builder for [`HttpAcl`].
433#[derive(Default, Clone)]
434#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
435pub struct HttpAclBuilder {
436    allow_http: bool,
437    allow_https: bool,
438    allowed_methods: Vec<HttpRequestMethod>,
439    denied_methods: Vec<HttpRequestMethod>,
440    allowed_hosts: Vec<String>,
441    denied_hosts: Vec<String>,
442    allowed_port_ranges: Vec<RangeInclusive<u16>>,
443    denied_port_ranges: Vec<RangeInclusive<u16>>,
444    allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
445    denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
446    static_dns_mapping: HashMap<String, SocketAddr>,
447    allowed_headers: HashMap<String, Option<String>>,
448    denied_headers: HashMap<String, Option<String>>,
449    allowed_url_paths: Vec<String>,
450    #[cfg_attr(feature = "serde", serde(skip))]
451    allowed_url_paths_router: Router<()>,
452    denied_url_paths: Vec<String>,
453    #[cfg_attr(feature = "serde", serde(skip))]
454    denied_url_paths_router: Router<()>,
455    allow_private_ip_ranges: bool,
456    method_acl_default: bool,
457    host_acl_default: bool,
458    port_acl_default: bool,
459    ip_acl_default: bool,
460    header_acl_default: bool,
461    url_path_acl_default: bool,
462}
463
464impl std::fmt::Debug for HttpAclBuilder {
465    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
466        f.debug_struct("HttpAclBuilder")
467            .field("allow_http", &self.allow_http)
468            .field("allow_https", &self.allow_https)
469            .field("allowed_methods", &self.allowed_methods)
470            .field("denied_methods", &self.denied_methods)
471            .field("allowed_hosts", &self.allowed_hosts)
472            .field("denied_hosts", &self.denied_hosts)
473            .field("allowed_port_ranges", &self.allowed_port_ranges)
474            .field("denied_port_ranges", &self.denied_port_ranges)
475            .field("allowed_ip_ranges", &self.allowed_ip_ranges)
476            .field("denied_ip_ranges", &self.denied_ip_ranges)
477            .field("static_dns_mapping", &self.static_dns_mapping)
478            .field("allowed_headers", &self.allowed_headers)
479            .field("denied_headers", &self.denied_headers)
480            .field("allowed_url_paths", &self.allowed_url_paths)
481            .field("denied_url_paths", &self.denied_url_paths)
482            .field("allow_private_ip_ranges", &self.allow_private_ip_ranges)
483            .field("method_acl_default", &self.method_acl_default)
484            .field("host_acl_default", &self.host_acl_default)
485            .field("port_acl_default", &self.port_acl_default)
486            .field("ip_acl_default", &self.ip_acl_default)
487            .field("header_acl_default", &self.header_acl_default)
488            .field("url_path_acl_default", &self.url_path_acl_default)
489            .finish()
490    }
491}
492
493impl PartialEq for HttpAclBuilder {
494    fn eq(&self, other: &Self) -> bool {
495        self.allow_http == other.allow_http
496            && self.allow_https == other.allow_https
497            && self.allowed_methods == other.allowed_methods
498            && self.denied_methods == other.denied_methods
499            && self.allowed_hosts == other.allowed_hosts
500            && self.denied_hosts == other.denied_hosts
501            && self.allowed_port_ranges == other.allowed_port_ranges
502            && self.denied_port_ranges == other.denied_port_ranges
503            && self.allowed_ip_ranges == other.allowed_ip_ranges
504            && self.denied_ip_ranges == other.denied_ip_ranges
505            && self.static_dns_mapping == other.static_dns_mapping
506            && self.allowed_headers == other.allowed_headers
507            && self.denied_headers == other.denied_headers
508            && self.allowed_url_paths == other.allowed_url_paths
509            && self.denied_url_paths == other.denied_url_paths
510            && self.allow_private_ip_ranges == other.allow_private_ip_ranges
511            && self.method_acl_default == other.method_acl_default
512            && self.host_acl_default == other.host_acl_default
513            && self.port_acl_default == other.port_acl_default
514            && self.ip_acl_default == other.ip_acl_default
515            && self.header_acl_default == other.header_acl_default
516            && self.url_path_acl_default == other.url_path_acl_default
517    }
518}
519
520impl HttpAclBuilder {
521    /// Create a new [`HttpAclBuilder`].
522    pub fn new() -> Self {
523        Self {
524            allow_http: true,
525            allow_https: true,
526            allowed_methods: vec![
527                HttpRequestMethod::CONNECT,
528                HttpRequestMethod::DELETE,
529                HttpRequestMethod::GET,
530                HttpRequestMethod::HEAD,
531                HttpRequestMethod::OPTIONS,
532                HttpRequestMethod::PATCH,
533                HttpRequestMethod::POST,
534                HttpRequestMethod::PUT,
535                HttpRequestMethod::TRACE,
536            ],
537            denied_methods: Vec::new(),
538            allowed_hosts: Vec::new(),
539            denied_hosts: Vec::new(),
540            allowed_port_ranges: vec![80..=80, 443..=443],
541            denied_port_ranges: Vec::new(),
542            allowed_ip_ranges: Vec::new(),
543            denied_ip_ranges: Vec::new(),
544            allowed_headers: HashMap::new(),
545            denied_headers: HashMap::new(),
546            allowed_url_paths: Vec::new(),
547            allowed_url_paths_router: Router::new(),
548            denied_url_paths: Vec::new(),
549            denied_url_paths_router: Router::new(),
550            allow_private_ip_ranges: false,
551            static_dns_mapping: HashMap::new(),
552            method_acl_default: false,
553            host_acl_default: false,
554            port_acl_default: false,
555            ip_acl_default: false,
556            header_acl_default: true,
557            url_path_acl_default: true,
558        }
559    }
560
561    /// Sets whether HTTP is allowed.
562    pub fn http(mut self, allow: bool) -> Self {
563        self.allow_http = allow;
564        self
565    }
566
567    /// Sets whether HTTPS is allowed.
568    pub fn https(mut self, allow: bool) -> Self {
569        self.allow_https = allow;
570        self
571    }
572
573    /// Sets whether private IP ranges are allowed.
574    pub fn private_ip_ranges(mut self, allow: bool) -> Self {
575        self.allow_private_ip_ranges = allow;
576        self
577    }
578
579    /// Set default action for HTTP methods if no ACL match is found.
580    pub fn method_acl_default(mut self, allow: bool) -> Self {
581        self.method_acl_default = allow;
582        self
583    }
584
585    /// Set default action for hosts if no ACL match is found.
586    pub fn host_acl_default(mut self, allow: bool) -> Self {
587        self.host_acl_default = allow;
588        self
589    }
590
591    /// Set default action for ports if no ACL match is found.
592    pub fn port_acl_default(mut self, allow: bool) -> Self {
593        self.port_acl_default = allow;
594        self
595    }
596
597    /// Set default action for IPs if no ACL match is found.
598    pub fn ip_acl_default(mut self, allow: bool) -> Self {
599        self.ip_acl_default = allow;
600        self
601    }
602
603    /// Set default action for headers if no ACL match is found.
604    pub fn header_acl_default(mut self, allow: bool) -> Self {
605        self.header_acl_default = allow;
606        self
607    }
608
609    /// Set default action for URL paths if no ACL match is found.
610    pub fn url_path_acl_default(mut self, allow: bool) -> Self {
611        self.url_path_acl_default = allow;
612        self
613    }
614
615    /// Adds a method to the allowed methods.
616    pub fn add_allowed_method(
617        mut self,
618        method: impl Into<HttpRequestMethod>,
619    ) -> Result<Self, AddError> {
620        let method = method.into();
621        if self.denied_methods.contains(&method) {
622            Err(AddError::AlreadyDeniedMethod(method))
623        } else if self.allowed_methods.contains(&method) {
624            Err(AddError::AlreadyAllowedMethod(method))
625        } else {
626            self.allowed_methods.push(method);
627            Ok(self)
628        }
629    }
630
631    /// Removes a method from the allowed methods.
632    pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
633        let method = method.into();
634        self.allowed_methods.retain(|m| m != &method);
635        self
636    }
637
638    /// Sets the allowed methods.
639    pub fn allowed_methods(
640        mut self,
641        methods: Vec<impl Into<HttpRequestMethod>>,
642    ) -> Result<Self, AddError> {
643        let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
644
645        for method in &methods {
646            if self.denied_methods.contains(method) {
647                return Err(AddError::AlreadyDeniedMethod(method.clone()));
648            }
649        }
650        self.allowed_methods = methods;
651        Ok(self)
652    }
653
654    /// Clears the allowed methods.
655    pub fn clear_allowed_methods(mut self) -> Self {
656        self.allowed_methods.clear();
657        self
658    }
659
660    /// Adds a method to the denied methods.
661    pub fn add_denied_method(
662        mut self,
663        method: impl Into<HttpRequestMethod>,
664    ) -> Result<Self, AddError> {
665        let method = method.into();
666        if self.allowed_methods.contains(&method) {
667            Err(AddError::AlreadyAllowedMethod(method))
668        } else if self.denied_methods.contains(&method) {
669            Err(AddError::AlreadyDeniedMethod(method))
670        } else {
671            self.denied_methods.push(method);
672            Ok(self)
673        }
674    }
675
676    /// Removes a method from the denied methods.
677    pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
678        let method = method.into();
679        self.denied_methods.retain(|m| m != &method);
680        self
681    }
682
683    /// Sets the denied methods.
684    pub fn denied_methods(
685        mut self,
686        methods: Vec<impl Into<HttpRequestMethod>>,
687    ) -> Result<Self, AddError> {
688        let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
689
690        for method in &methods {
691            if self.allowed_methods.contains(method) {
692                return Err(AddError::AlreadyAllowedMethod(method.clone()));
693            }
694        }
695        self.denied_methods = methods;
696        Ok(self)
697    }
698
699    /// Clears the denied methods.
700    pub fn clear_denied_methods(mut self) -> Self {
701        self.denied_methods.clear();
702        self
703    }
704
705    /// Sets whether public IP ranges are allowed.
706    pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
707        if utils::authority::is_valid_host(&host) {
708            if self.denied_hosts.contains(&host) {
709                Err(AddError::AlreadyDeniedHost(host))
710            } else if self.allowed_hosts.contains(&host) {
711                Err(AddError::AlreadyAllowedHost(host))
712            } else {
713                self.allowed_hosts.push(host);
714                Ok(self)
715            }
716        } else {
717            Err(AddError::InvalidEntity(host))
718        }
719    }
720
721    /// Removes a host from the allowed hosts.
722    pub fn remove_allowed_host(mut self, host: String) -> Self {
723        self.allowed_hosts.retain(|h| h != &host);
724        self
725    }
726
727    /// Sets the allowed hosts.
728    pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
729        for host in &hosts {
730            if utils::authority::is_valid_host(host) {
731                if self.denied_hosts.contains(host) {
732                    return Err(AddError::AlreadyDeniedHost(host.clone()));
733                }
734            } else {
735                return Err(AddError::InvalidEntity(host.clone()));
736            }
737        }
738        self.allowed_hosts = hosts;
739        Ok(self)
740    }
741
742    /// Clears the allowed hosts.
743    pub fn clear_allowed_hosts(mut self) -> Self {
744        self.allowed_hosts.clear();
745        self
746    }
747
748    /// Adds a host to the denied hosts.
749    pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
750        if utils::authority::is_valid_host(&host) {
751            if self.allowed_hosts.contains(&host) {
752                Err(AddError::AlreadyAllowedHost(host))
753            } else if self.denied_hosts.contains(&host) {
754                Err(AddError::AlreadyDeniedHost(host))
755            } else {
756                self.denied_hosts.push(host);
757                Ok(self)
758            }
759        } else {
760            Err(AddError::InvalidEntity(host))
761        }
762    }
763
764    /// Removes a host from the denied hosts.
765    pub fn remove_denied_host(mut self, host: String) -> Self {
766        self.denied_hosts.retain(|h| h != &host);
767        self
768    }
769
770    /// Sets the denied hosts.
771    pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
772        for host in &hosts {
773            if utils::authority::is_valid_host(host) {
774                if self.allowed_hosts.contains(host) {
775                    return Err(AddError::AlreadyAllowedHost(host.clone()));
776                }
777            } else {
778                return Err(AddError::InvalidEntity(host.clone()));
779            }
780        }
781        self.denied_hosts = hosts;
782        Ok(self)
783    }
784
785    /// Clears the denied hosts.
786    pub fn clear_denied_hosts(mut self) -> Self {
787        self.denied_hosts.clear();
788        self
789    }
790
791    /// Adds a port range to the allowed port ranges.
792    pub fn add_allowed_port_range(
793        mut self,
794        port_range: RangeInclusive<u16>,
795    ) -> Result<Self, AddError> {
796        if self.denied_port_ranges.contains(&port_range) {
797            Err(AddError::AlreadyDeniedPortRange(port_range))
798        } else if self.allowed_port_ranges.contains(&port_range) {
799            Err(AddError::AlreadyAllowedPortRange(port_range))
800        } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
801            || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
802        {
803            Err(AddError::Overlaps(format!("{:?}", port_range)))
804        } else {
805            self.allowed_port_ranges.push(port_range);
806            Ok(self)
807        }
808    }
809
810    /// Removes a port range from the allowed port ranges.
811    pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
812        self.allowed_port_ranges.retain(|p| p != &port_range);
813        self
814    }
815
816    /// Sets the allowed port ranges.
817    pub fn allowed_port_ranges(
818        mut self,
819        port_ranges: Vec<RangeInclusive<u16>>,
820    ) -> Result<Self, AddError> {
821        for (i, port_range) in port_ranges.iter().enumerate() {
822            if self.denied_port_ranges.contains(port_range) {
823                return Err(AddError::AlreadyDeniedPortRange(port_range.clone()));
824            } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
825                || utils::range_overlaps(&self.denied_port_ranges, port_range, None)
826            {
827                return Err(AddError::Overlaps(format!("{:?}", port_range)));
828            }
829        }
830        self.allowed_port_ranges = port_ranges;
831        Ok(self)
832    }
833
834    /// Clears the allowed port ranges.
835    pub fn clear_allowed_port_ranges(mut self) -> Self {
836        self.allowed_port_ranges.clear();
837        self
838    }
839
840    /// Adds a port range to the denied port ranges.
841    pub fn add_denied_port_range(
842        mut self,
843        port_range: RangeInclusive<u16>,
844    ) -> Result<Self, AddError> {
845        if self.allowed_port_ranges.contains(&port_range) {
846            Err(AddError::AlreadyAllowedPortRange(port_range))
847        } else if self.denied_port_ranges.contains(&port_range) {
848            Err(AddError::AlreadyDeniedPortRange(port_range))
849        } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
850            || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
851        {
852            Err(AddError::Overlaps(format!("{:?}", port_range)))
853        } else {
854            self.denied_port_ranges.push(port_range);
855            Ok(self)
856        }
857    }
858
859    /// Removes a port range from the denied port ranges.
860    pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
861        self.denied_port_ranges.retain(|p| p != &port_range);
862        self
863    }
864
865    /// Sets the denied port ranges.
866    pub fn denied_port_ranges(
867        mut self,
868        port_ranges: Vec<RangeInclusive<u16>>,
869    ) -> Result<Self, AddError> {
870        for port_range in &port_ranges {
871            if self.allowed_port_ranges.contains(port_range) {
872                return Err(AddError::AlreadyAllowedPortRange(port_range.clone()));
873            }
874        }
875        self.denied_port_ranges = port_ranges;
876        Ok(self)
877    }
878
879    /// Clears the denied port ranges.
880    pub fn clear_denied_port_ranges(mut self) -> Self {
881        self.denied_port_ranges.clear();
882        self
883    }
884
885    /// Adds an IP range to the allowed IP ranges.
886    pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
887        let ip_range = ip_range
888            .into_range()
889            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
890        if self.denied_ip_ranges.contains(&ip_range) {
891            return Err(AddError::AlreadyDeniedIpRange(ip_range));
892        } else if self.allowed_ip_ranges.contains(&ip_range) {
893            return Err(AddError::AlreadyAllowedIpRange(ip_range));
894        } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
895            || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
896        {
897            return Err(AddError::Overlaps(format!("{:?}", ip_range)));
898        }
899        self.allowed_ip_ranges.push(ip_range);
900        Ok(self)
901    }
902
903    /// Removes an IP range from the allowed IP ranges.
904    pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
905        mut self,
906        ip_range: Ip,
907    ) -> Result<Self, AddError> {
908        let ip_range = ip_range
909            .into_range()
910            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
911        self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
912        Ok(self)
913    }
914
915    /// Sets the allowed IP ranges.
916    pub fn allowed_ip_ranges<Ip: IntoIpRange>(
917        mut self,
918        ip_ranges: Vec<Ip>,
919    ) -> Result<Self, AddError> {
920        let ip_ranges = ip_ranges
921            .into_iter()
922            .map(|ip| ip.into_range())
923            .collect::<Option<Vec<_>>>()
924            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
925        for (i, ip_range) in ip_ranges.iter().enumerate() {
926            if self.denied_ip_ranges.contains(ip_range) {
927                return Err(AddError::AlreadyDeniedIpRange(ip_range.clone()));
928            } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
929                || utils::range_overlaps(&self.denied_ip_ranges, ip_range, None)
930            {
931                return Err(AddError::Overlaps(format!("{:?}", ip_range)));
932            }
933        }
934        self.allowed_ip_ranges = ip_ranges;
935        Ok(self)
936    }
937
938    /// Clears the allowed IP ranges.
939    pub fn clear_allowed_ip_ranges(mut self) -> Self {
940        self.allowed_ip_ranges.clear();
941        self
942    }
943
944    /// Adds an IP range to the denied IP ranges.
945    pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
946        let ip_range = ip_range
947            .into_range()
948            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
949        if self.allowed_ip_ranges.contains(&ip_range) {
950            return Err(AddError::AlreadyAllowedIpRange(ip_range));
951        } else if self.denied_ip_ranges.contains(&ip_range) {
952            return Err(AddError::AlreadyDeniedIpRange(ip_range));
953        } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
954            || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
955        {
956            return Err(AddError::Overlaps(format!("{:?}", ip_range)));
957        }
958        self.denied_ip_ranges.push(ip_range);
959        Ok(self)
960    }
961
962    /// Removes an IP range from the denied IP ranges.
963    pub fn remove_denied_ip_range<Ip: IntoIpRange>(
964        mut self,
965        ip_range: Ip,
966    ) -> Result<Self, AddError> {
967        let ip_range = ip_range
968            .into_range()
969            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
970        self.denied_ip_ranges.retain(|ip| ip != &ip_range);
971        Ok(self)
972    }
973
974    /// Sets the denied IP ranges.
975    pub fn denied_ip_ranges<Ip: IntoIpRange>(
976        mut self,
977        ip_ranges: Vec<Ip>,
978    ) -> Result<Self, AddError> {
979        let ip_ranges = ip_ranges
980            .into_iter()
981            .map(|ip| ip.into_range())
982            .collect::<Option<Vec<_>>>()
983            .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
984        for (i, ip_range) in ip_ranges.iter().enumerate() {
985            if self.allowed_ip_ranges.contains(ip_range) {
986                return Err(AddError::AlreadyAllowedIpRange(ip_range.clone()));
987            } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
988                || utils::range_overlaps(&self.allowed_ip_ranges, ip_range, None)
989            {
990                return Err(AddError::Overlaps(format!("{:?}", ip_range)));
991            }
992        }
993        self.denied_ip_ranges = ip_ranges;
994        Ok(self)
995    }
996
997    /// Clears the denied IP ranges.
998    pub fn clear_denied_ip_ranges(mut self) -> Self {
999        self.denied_ip_ranges.clear();
1000        self
1001    }
1002
1003    /// Add a static DNS mapping.
1004    pub fn add_static_dns_mapping(
1005        mut self,
1006        host: String,
1007        sock_addr: SocketAddr,
1008    ) -> Result<Self, AddError> {
1009        if utils::authority::is_valid_host(&host) {
1010            if let Entry::Vacant(e) = self.static_dns_mapping.entry(host.clone()) {
1011                e.insert(sock_addr);
1012                Ok(self)
1013            } else {
1014                Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr))
1015            }
1016        } else {
1017            Err(AddError::InvalidEntity(host))
1018        }
1019    }
1020
1021    /// Removes a static DNS mapping.
1022    pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
1023        self.static_dns_mapping.remove(host);
1024        self
1025    }
1026
1027    /// Sets the static DNS mappings.
1028    pub fn static_dns_mappings(
1029        mut self,
1030        mappings: HashMap<String, SocketAddr>,
1031    ) -> Result<Self, AddError> {
1032        for (host, ip) in &mappings {
1033            if utils::authority::is_valid_host(host) {
1034                if self.static_dns_mapping.contains_key(host) {
1035                    return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1036                }
1037                self.static_dns_mapping.insert(host.to_string(), *ip);
1038            } else {
1039                return Err(AddError::InvalidEntity(host.clone()));
1040            }
1041        }
1042        Ok(self)
1043    }
1044
1045    /// Clears the static DNS mappings.
1046    pub fn clear_static_dns_mappings(mut self) -> Self {
1047        self.static_dns_mapping.clear();
1048        self
1049    }
1050
1051    /// Adds a header to the allowed headers.
1052    pub fn add_allowed_header(
1053        mut self,
1054        header: String,
1055        value: Option<String>,
1056    ) -> Result<Self, AddError> {
1057        if self.denied_headers.contains_key(&header) {
1058            Err(AddError::AlreadyDeniedHeader(header, value.clone()))
1059        } else if let Entry::Vacant(e) = self.allowed_headers.entry(header.clone()) {
1060            e.insert(value);
1061            Ok(self)
1062        } else {
1063            Err(AddError::AlreadyAllowedHeader(header, value))
1064        }
1065    }
1066
1067    /// Removes a header from the allowed headers.
1068    pub fn remove_allowed_header(mut self, header: &str) -> Self {
1069        self.allowed_headers.remove(header);
1070        self
1071    }
1072
1073    /// Sets the allowed headers.
1074    pub fn allowed_headers(
1075        mut self,
1076        headers: HashMap<String, Option<String>>,
1077    ) -> Result<Self, AddError> {
1078        for (header, value) in &headers {
1079            if self.denied_headers.contains_key(header) {
1080                return Err(AddError::AlreadyDeniedHeader(header.clone(), value.clone()));
1081            }
1082        }
1083        self.allowed_headers = headers;
1084        Ok(self)
1085    }
1086
1087    /// Clears the allowed headers.
1088    pub fn clear_allowed_headers(mut self) -> Self {
1089        self.allowed_headers.clear();
1090        self
1091    }
1092
1093    /// Adds a header to the denied headers.
1094    pub fn add_denied_header(
1095        mut self,
1096        header: String,
1097        value: Option<String>,
1098    ) -> Result<Self, AddError> {
1099        if self.allowed_headers.contains_key(&header) {
1100            Err(AddError::AlreadyAllowedHeader(header, value.clone()))
1101        } else if let Entry::Vacant(e) = self.denied_headers.entry(header.clone()) {
1102            e.insert(value);
1103            Ok(self)
1104        } else {
1105            Err(AddError::AlreadyDeniedHeader(header, value))
1106        }
1107    }
1108
1109    /// Removes a header from the denied headers.
1110    pub fn remove_denied_header(mut self, header: &str) -> Self {
1111        self.denied_headers.remove(header);
1112        self
1113    }
1114
1115    /// Sets the denied headers.
1116    pub fn denied_headers(
1117        mut self,
1118        headers: HashMap<String, Option<String>>,
1119    ) -> Result<Self, AddError> {
1120        for (header, value) in &headers {
1121            if self.allowed_headers.contains_key(header) {
1122                return Err(AddError::AlreadyAllowedHeader(
1123                    header.clone(),
1124                    value.clone(),
1125                ));
1126            }
1127        }
1128        self.denied_headers = headers;
1129        Ok(self)
1130    }
1131
1132    /// Clears the denied headers.
1133    pub fn clear_denied_headers(mut self) -> Self {
1134        self.denied_headers.clear();
1135        self
1136    }
1137
1138    /// Adds a URL path to the allowed URL paths.
1139    pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1140        if self.denied_url_paths.contains(&url_path)
1141            || self.denied_url_paths_router.at(&url_path).is_ok()
1142        {
1143            Err(AddError::AlreadyDeniedUrlPath(url_path))
1144        } else if self.allowed_url_paths.contains(&url_path)
1145            || self.allowed_url_paths_router.at(&url_path).is_ok()
1146        {
1147            Err(AddError::AlreadyAllowedUrlPath(url_path))
1148        } else {
1149            self.allowed_url_paths.push(url_path.clone());
1150            self.allowed_url_paths_router
1151                .insert(url_path, ())
1152                .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1153            Ok(self)
1154        }
1155    }
1156
1157    /// Removes a URL path from the allowed URL paths.
1158    pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1159        self.allowed_url_paths.retain(|p| p != url_path);
1160        self.allowed_url_paths_router = {
1161            let mut router = Router::new();
1162            for url_path in &self.allowed_url_paths {
1163                router
1164                    .insert(url_path.clone(), ())
1165                    .expect("failed to insert url path");
1166            }
1167            router
1168        };
1169        self
1170    }
1171
1172    /// Sets the allowed URL paths.
1173    pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1174        for url_path in &url_paths {
1175            if self.denied_url_paths.contains(url_path)
1176                || self.denied_url_paths_router.at(url_path).is_ok()
1177            {
1178                return Err(AddError::AlreadyDeniedUrlPath(url_path.clone()));
1179            }
1180        }
1181        self.allowed_url_paths_router = Router::new();
1182        for url_path in &url_paths {
1183            self.allowed_url_paths_router
1184                .insert(url_path.clone(), ())
1185                .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {}", url_path)))?;
1186        }
1187        self.allowed_url_paths = url_paths;
1188        Ok(self)
1189    }
1190
1191    /// Clears the allowed URL paths.
1192    pub fn clear_allowed_url_paths(mut self) -> Self {
1193        self.allowed_url_paths.clear();
1194        self.allowed_url_paths_router = Router::new();
1195        self
1196    }
1197
1198    /// Adds a URL path to the denied URL paths.
1199    pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1200        if self.allowed_url_paths.contains(&url_path)
1201            || self.allowed_url_paths_router.at(&url_path).is_ok()
1202        {
1203            Err(AddError::AlreadyAllowedUrlPath(url_path))
1204        } else if self.denied_url_paths.contains(&url_path)
1205            || self.denied_url_paths_router.at(&url_path).is_ok()
1206        {
1207            Err(AddError::AlreadyDeniedUrlPath(url_path))
1208        } else {
1209            self.denied_url_paths.push(url_path.clone());
1210            self.denied_url_paths_router
1211                .insert(url_path, ())
1212                .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1213            Ok(self)
1214        }
1215    }
1216
1217    /// Removes a URL path from the denied URL paths.
1218    pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1219        self.denied_url_paths.retain(|p| p != url_path);
1220        self.denied_url_paths_router = {
1221            let mut router = Router::new();
1222            for url_path in &self.denied_url_paths {
1223                router
1224                    .insert(url_path.clone(), ())
1225                    .expect("failed to insert url path");
1226            }
1227            router
1228        };
1229        self
1230    }
1231
1232    /// Sets the denied URL paths.
1233    pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1234        for url_path in &url_paths {
1235            if self.allowed_url_paths.contains(url_path)
1236                || self.allowed_url_paths_router.at(url_path).is_ok()
1237            {
1238                return Err(AddError::AlreadyAllowedUrlPath(url_path.clone()));
1239            }
1240        }
1241        self.denied_url_paths_router = Router::new();
1242        for url_path in &url_paths {
1243            self.denied_url_paths_router
1244                .insert(url_path.clone(), ())
1245                .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {}", url_path)))?;
1246        }
1247        self.denied_url_paths = url_paths;
1248        Ok(self)
1249    }
1250
1251    /// Clears the denied URL paths.
1252    pub fn clear_denied_url_paths(mut self) -> Self {
1253        self.denied_url_paths.clear();
1254        self.denied_url_paths_router = Router::new();
1255        self
1256    }
1257
1258    /// Builds the [`HttpAcl`].
1259    pub fn build(self) -> HttpAcl {
1260        self.build_full(None)
1261    }
1262
1263    /// Builds the [`HttpAcl`].
1264    pub fn build_full(self, validate_fn: Option<ValidateFn>) -> HttpAcl {
1265        HttpAcl {
1266            allow_http: self.allow_http,
1267            allow_https: self.allow_https,
1268            allowed_methods: self.allowed_methods.into_iter().collect(),
1269            denied_methods: self.denied_methods.into_iter().collect(),
1270            allowed_hosts: self
1271                .allowed_hosts
1272                .into_iter()
1273                .map(|x| x.into_boxed_str())
1274                .collect(),
1275            denied_hosts: self
1276                .denied_hosts
1277                .into_iter()
1278                .map(|x| x.into_boxed_str())
1279                .collect(),
1280            allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1281            denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1282            allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1283            denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1284            allowed_headers: self
1285                .allowed_headers
1286                .into_iter()
1287                .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1288                .collect(),
1289            denied_headers: self
1290                .denied_headers
1291                .into_iter()
1292                .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1293                .collect(),
1294            allowed_url_paths_router: self.allowed_url_paths_router,
1295            denied_url_paths_router: self.denied_url_paths_router,
1296            static_dns_mapping: self
1297                .static_dns_mapping
1298                .into_iter()
1299                .map(|(k, v)| (k.into_boxed_str(), v))
1300                .collect(),
1301            validate_fn,
1302            allow_private_ip_ranges: self.allow_private_ip_ranges,
1303            method_acl_default: self.method_acl_default,
1304            host_acl_default: self.host_acl_default,
1305            port_acl_default: self.port_acl_default,
1306            ip_acl_default: self.ip_acl_default,
1307            header_acl_default: self.header_acl_default,
1308            url_path_acl_default: self.url_path_acl_default,
1309        }
1310    }
1311
1312    /// Builds the [`HttpAcl`] and returns an error if the configuration is invalid.
1313    /// This is used for deserialized ACLs as the URL Path Routers need to be built.
1314    pub fn try_build_full(mut self, validate_fn: Option<ValidateFn>) -> Result<HttpAcl, AddError> {
1315        if !utils::has_unique_elements(&self.allowed_methods) {
1316            return Err(AddError::NotUnique(
1317                "Allowed methods must be unique.".to_string(),
1318            ));
1319        }
1320        for method in &self.allowed_methods {
1321            if self.denied_methods.contains(method) {
1322                return Err(AddError::BothAllowedAndDenied(format!(
1323                    "Method `{}`",
1324                    method.as_str()
1325                )));
1326            }
1327        }
1328        if !utils::has_unique_elements(&self.denied_methods) {
1329            return Err(AddError::NotUnique(
1330                "Denied methods must be unique.".to_string(),
1331            ));
1332        }
1333        for method in &self.denied_methods {
1334            if self.allowed_methods.contains(method) {
1335                return Err(AddError::BothAllowedAndDenied(format!(
1336                    "Method `{}`",
1337                    method.as_str()
1338                )));
1339            }
1340        }
1341        if !utils::has_unique_elements(&self.allowed_hosts) {
1342            return Err(AddError::NotUnique(
1343                "Allowed hosts must be unique.".to_string(),
1344            ));
1345        }
1346        for host in &self.allowed_hosts {
1347            if !utils::authority::is_valid_host(host) {
1348                return Err(AddError::InvalidEntity(host.to_string()));
1349            }
1350            if self.denied_hosts.contains(host) {
1351                return Err(AddError::BothAllowedAndDenied(format!("Host `{}`", host)));
1352            }
1353        }
1354        if !utils::has_unique_elements(&self.denied_hosts) {
1355            return Err(AddError::NotUnique(
1356                "Denied hosts must be unique.".to_string(),
1357            ));
1358        }
1359        for host in &self.denied_hosts {
1360            if !utils::authority::is_valid_host(host) {
1361                return Err(AddError::InvalidEntity(host.to_string()));
1362            }
1363            if self.allowed_hosts.contains(host) {
1364                return Err(AddError::BothAllowedAndDenied(format!("Host `{}`", host)));
1365            }
1366        }
1367        if !utils::has_unique_elements(&self.allowed_port_ranges) {
1368            return Err(AddError::NotUnique(
1369                "Allowed port ranges must be unique.".to_string(),
1370            ));
1371        }
1372        if utils::has_overlapping_ranges(&self.allowed_port_ranges) {
1373            return Err(AddError::Overlaps(
1374                "Allowed port ranges must not overlap.".to_string(),
1375            ));
1376        }
1377        for port_range in &self.allowed_port_ranges {
1378            if self.denied_port_ranges.contains(port_range) {
1379                return Err(AddError::BothAllowedAndDenied(format!(
1380                    "Port range `{:?}`",
1381                    port_range
1382                )));
1383            }
1384        }
1385        if !utils::has_unique_elements(&self.denied_port_ranges) {
1386            return Err(AddError::NotUnique(
1387                "Denied port ranges must be unique.".to_string(),
1388            ));
1389        }
1390        if utils::has_overlapping_ranges(&self.denied_port_ranges) {
1391            return Err(AddError::Overlaps(
1392                "Denied port ranges must not overlap.".to_string(),
1393            ));
1394        }
1395        for port_range in &self.denied_port_ranges {
1396            if self.allowed_port_ranges.contains(port_range) {
1397                return Err(AddError::BothAllowedAndDenied(format!(
1398                    "Port range `{:?}`",
1399                    port_range
1400                )));
1401            }
1402        }
1403        if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1404            return Err(AddError::NotUnique(
1405                "Allowed IP ranges must be unique.".to_string(),
1406            ));
1407        }
1408        if utils::has_overlapping_ranges(&self.allowed_ip_ranges) {
1409            return Err(AddError::Overlaps(
1410                "Allowed IP ranges must not overlap.".to_string(),
1411            ));
1412        }
1413        for ip_range in &self.allowed_ip_ranges {
1414            if self.denied_ip_ranges.contains(ip_range) {
1415                return Err(AddError::BothAllowedAndDenied(format!(
1416                    "IP range `{:?}`",
1417                    ip_range
1418                )));
1419            }
1420        }
1421        if !utils::has_unique_elements(&self.denied_ip_ranges) {
1422            return Err(AddError::NotUnique(
1423                "Denied IP ranges must be unique.".to_string(),
1424            ));
1425        }
1426        if utils::has_overlapping_ranges(&self.denied_ip_ranges) {
1427            return Err(AddError::Overlaps(
1428                "Denied IP ranges must not overlap.".to_string(),
1429            ));
1430        }
1431        for ip_range in &self.denied_ip_ranges {
1432            if self.allowed_ip_ranges.contains(ip_range) {
1433                return Err(AddError::BothAllowedAndDenied(format!(
1434                    "IP range `{:?}`",
1435                    ip_range
1436                )));
1437            }
1438        }
1439        if !utils::has_unique_elements(&self.static_dns_mapping) {
1440            return Err(AddError::NotUnique(
1441                "Static DNS mapping must be unique.".to_string(),
1442            ));
1443        }
1444        for host in self.static_dns_mapping.keys() {
1445            if !utils::authority::is_valid_host(host) {
1446                return Err(AddError::InvalidEntity(host.to_string()));
1447            }
1448        }
1449        if !utils::has_unique_elements(&self.allowed_url_paths) {
1450            return Err(AddError::NotUnique(
1451                "Allowed URL paths must be unique.".to_string(),
1452            ));
1453        }
1454        for url_path in &self.allowed_url_paths {
1455            if self.denied_url_paths.contains(url_path)
1456                || self.denied_url_paths_router.at(url_path).is_ok()
1457            {
1458                return Err(AddError::BothAllowedAndDenied(format!(
1459                    "URL path `{}`",
1460                    url_path
1461                )));
1462            } else if self.allowed_url_paths_router.at(url_path).is_err() {
1463                self.allowed_url_paths_router
1464                    .insert(url_path.clone(), ())
1465                    .map_err(|_| {
1466                        AddError::InvalidEntity(format!(
1467                            "Failed to insert allowed URL path `{}`.",
1468                            url_path
1469                        ))
1470                    })?;
1471            }
1472        }
1473        if !utils::has_unique_elements(&self.denied_url_paths) {
1474            return Err(AddError::NotUnique(
1475                "Denied URL paths must be unique.".to_string(),
1476            ));
1477        }
1478        for url_path in &self.denied_url_paths {
1479            if self.allowed_url_paths.contains(url_path)
1480                || self.allowed_url_paths_router.at(url_path).is_ok()
1481            {
1482                return Err(AddError::BothAllowedAndDenied(format!(
1483                    "URL path `{}`",
1484                    url_path
1485                )));
1486            } else if self.denied_url_paths_router.at(url_path).is_err() {
1487                self.denied_url_paths_router
1488                    .insert(url_path.clone(), ())
1489                    .map_err(|_| {
1490                        AddError::InvalidEntity(format!(
1491                            "Failed to insert denied URL path `{}`.",
1492                            url_path
1493                        ))
1494                    })?;
1495            }
1496        }
1497        Ok(self.build_full(validate_fn))
1498    }
1499
1500    /// Builds the [`HttpAcl`] and returns an error if the configuration is invalid.
1501    /// This is used for deserialized ACLs as the URL Path Routers need to be built.
1502    pub fn try_build(self) -> Result<HttpAcl, AddError> {
1503        self.try_build_full(None)
1504    }
1505}