http_acl/
acl.rs

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