1#[cfg(feature = "hashbrown")]
15use hashbrown::{HashMap, HashSet, hash_map::Entry};
16#[cfg(not(feature = "hashbrown"))]
17use std::collections::{HashMap, HashSet, hash_map::Entry};
18use std::hash::Hash;
19use std::net::{IpAddr, SocketAddr};
20use std::ops::RangeInclusive;
21use std::sync::Arc;
22
23use matchit::Router;
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Serialize};
26
27use crate::{
28 error::AddError,
29 utils::{
30 self, IntoIpRange,
31 authority::Authority,
32 host_pattern::{HostPattern, is_wildcard_host},
33 },
34};
35
36pub type ValidateFn = Arc<
49 dyn for<'h> Fn(
50 &str,
51 &Authority,
52 Box<dyn Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h>,
53 Option<&[u8]>,
54 ) -> AclClassification
55 + Send
56 + Sync,
57>;
58
59#[derive(Clone)]
60pub struct HttpAcl {
68 allow_http: bool,
69 allow_https: bool,
70 allowed_methods: HashSet<HttpRequestMethod>,
71 denied_methods: HashSet<HttpRequestMethod>,
72 allowed_hosts: HashSet<Box<str>>,
73 denied_hosts: HashSet<Box<str>>,
74 allowed_host_patterns: Box<[HostPattern]>,
75 denied_host_patterns: Box<[HostPattern]>,
76 allowed_port_ranges: Box<[RangeInclusive<u16>]>,
77 denied_port_ranges: Box<[RangeInclusive<u16>]>,
78 allowed_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
79 denied_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
80 static_dns_mapping: HashMap<Box<str>, SocketAddr>,
81 trusted_static_dns_mapping: HashMap<Box<str>, SocketAddr>,
82 allowed_headers: HashMap<Box<str>, Option<Box<str>>>,
83 denied_headers: HashMap<Box<str>, Option<Box<str>>>,
84 allowed_url_paths_router: Router<()>,
85 denied_url_paths_router: Router<()>,
86 validate_fn: Option<ValidateFn>,
87 allow_non_global_ip_ranges: bool,
88 method_acl_default: bool,
89 host_acl_default: bool,
90 port_acl_default: bool,
91 ip_acl_default: bool,
92 header_acl_default: bool,
93 url_path_acl_default: bool,
94}
95
96impl std::fmt::Debug for HttpAcl {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.debug_struct("HttpAcl")
99 .field("allow_http", &self.allow_http)
100 .field("allow_https", &self.allow_https)
101 .field("allowed_methods", &self.allowed_methods)
102 .field("denied_methods", &self.denied_methods)
103 .field("allowed_hosts", &self.allowed_hosts)
104 .field("denied_hosts", &self.denied_hosts)
105 .field("allowed_port_ranges", &self.allowed_port_ranges)
106 .field("denied_port_ranges", &self.denied_port_ranges)
107 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
108 .field("denied_ip_ranges", &self.denied_ip_ranges)
109 .field("static_dns_mapping", &self.static_dns_mapping)
110 .field(
111 "trusted_static_dns_mapping",
112 &self.trusted_static_dns_mapping,
113 )
114 .field("allowed_headers", &self.allowed_headers)
115 .field("denied_headers", &self.denied_headers)
116 .field(
117 "allow_non_global_ip_ranges",
118 &self.allow_non_global_ip_ranges,
119 )
120 .field("method_acl_default", &self.method_acl_default)
121 .field("host_acl_default", &self.host_acl_default)
122 .field("port_acl_default", &self.port_acl_default)
123 .field("ip_acl_default", &self.ip_acl_default)
124 .field("header_acl_default", &self.header_acl_default)
125 .field("url_path_acl_default", &self.url_path_acl_default)
126 .finish()
127 }
128}
129
130impl PartialEq for HttpAcl {
131 fn eq(&self, other: &Self) -> bool {
132 self.allow_http == other.allow_http
133 && self.allow_https == other.allow_https
134 && self.allowed_methods == other.allowed_methods
135 && self.denied_methods == other.denied_methods
136 && self.allowed_hosts == other.allowed_hosts
137 && self.denied_hosts == other.denied_hosts
138 && self.allowed_port_ranges == other.allowed_port_ranges
139 && self.denied_port_ranges == other.denied_port_ranges
140 && self.allowed_ip_ranges == other.allowed_ip_ranges
141 && self.denied_ip_ranges == other.denied_ip_ranges
142 && self.static_dns_mapping == other.static_dns_mapping
143 && self.trusted_static_dns_mapping == other.trusted_static_dns_mapping
144 && self.allowed_headers == other.allowed_headers
145 && self.denied_headers == other.denied_headers
146 && self.allow_non_global_ip_ranges == other.allow_non_global_ip_ranges
147 && self.method_acl_default == other.method_acl_default
148 && self.host_acl_default == other.host_acl_default
149 && self.port_acl_default == other.port_acl_default
150 && self.ip_acl_default == other.ip_acl_default
151 && self.header_acl_default == other.header_acl_default
152 && self.url_path_acl_default == other.url_path_acl_default
153 }
154}
155
156impl std::default::Default for HttpAcl {
157 fn default() -> Self {
158 Self {
159 allow_http: true,
160 allow_https: true,
161 allowed_methods: [
162 HttpRequestMethod::CONNECT,
163 HttpRequestMethod::DELETE,
164 HttpRequestMethod::GET,
165 HttpRequestMethod::HEAD,
166 HttpRequestMethod::OPTIONS,
167 HttpRequestMethod::PATCH,
168 HttpRequestMethod::POST,
169 HttpRequestMethod::PUT,
170 HttpRequestMethod::TRACE,
171 ]
172 .into_iter()
173 .collect(),
174 denied_methods: HashSet::new(),
175 allowed_hosts: HashSet::new(),
176 denied_hosts: HashSet::new(),
177 allowed_host_patterns: Box::new([]),
178 denied_host_patterns: Box::new([]),
179 allowed_port_ranges: vec![80..=80, 443..=443].into_boxed_slice(),
180 denied_port_ranges: Vec::new().into_boxed_slice(),
181 allowed_ip_ranges: Vec::new().into_boxed_slice(),
182 denied_ip_ranges: Vec::new().into_boxed_slice(),
183 static_dns_mapping: HashMap::new(),
184 trusted_static_dns_mapping: HashMap::new(),
185 allowed_headers: HashMap::new(),
186 denied_headers: HashMap::new(),
187 allowed_url_paths_router: Router::new(),
188 denied_url_paths_router: Router::new(),
189 validate_fn: None,
190 allow_non_global_ip_ranges: false,
191 method_acl_default: false,
192 host_acl_default: false,
193 port_acl_default: false,
194 ip_acl_default: false,
195 header_acl_default: true,
196 url_path_acl_default: true,
197 }
198 }
199}
200
201impl HttpAcl {
202 pub fn builder() -> HttpAclBuilder {
204 HttpAclBuilder::new()
205 }
206
207 pub fn is_scheme_allowed(&self, scheme: &str) -> AclClassification {
215 if scheme == "http" && self.allow_http || scheme == "https" && self.allow_https {
216 AclClassification::AllowedUserAcl
217 } else {
218 AclClassification::DeniedUserAcl
219 }
220 }
221
222 pub fn is_method_allowed(&self, method: impl Into<HttpRequestMethod>) -> AclClassification {
226 let method = method.into();
227 if self.allowed_methods.contains(&method) {
228 AclClassification::AllowedUserAcl
229 } else if self.denied_methods.contains(&method) {
230 AclClassification::DeniedUserAcl
231 } else if self.method_acl_default {
232 AclClassification::AllowedDefault
233 } else {
234 AclClassification::DeniedDefault
235 }
236 }
237
238 pub fn is_host_allowed(&self, host: &str) -> AclClassification {
245 if self.allowed_hosts.contains(host)
246 || self.allowed_host_patterns.iter().any(|p| p.matches(host))
247 {
248 AclClassification::AllowedUserAcl
249 } else if self.denied_hosts.contains(host)
250 || self.denied_host_patterns.iter().any(|p| p.matches(host))
251 {
252 AclClassification::DeniedUserAcl
253 } else if self.host_acl_default {
254 AclClassification::AllowedDefault
255 } else {
256 AclClassification::DeniedDefault
257 }
258 }
259
260 pub fn is_port_allowed(&self, port: u16) -> AclClassification {
262 if Self::is_port_in_ranges(port, &self.allowed_port_ranges) {
263 AclClassification::AllowedUserAcl
264 } else if Self::is_port_in_ranges(port, &self.denied_port_ranges) {
265 AclClassification::DeniedUserAcl
266 } else if self.port_acl_default {
267 AclClassification::AllowedDefault
268 } else {
269 AclClassification::DeniedDefault
270 }
271 }
272
273 pub fn is_ip_allowed(&self, ip: &IpAddr) -> AclClassification {
280 if !utils::ip::is_global_ip(ip) && !self.allow_non_global_ip_ranges {
281 AclClassification::DeniedNotGlobal
282 } else if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
283 AclClassification::AllowedUserAcl
284 } else if Self::is_ip_in_ranges(ip, &self.denied_ip_ranges) {
285 AclClassification::DeniedUserAcl
286 } else if self.ip_acl_default {
287 AclClassification::AllowedDefault
288 } else {
289 AclClassification::DeniedDefault
290 }
291 }
292
293 pub fn resolve_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
302 self.static_dns_mapping.get(host).copied()
303 }
304
305 pub fn resolve_trusted_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
314 self.trusted_static_dns_mapping.get(host).copied()
315 }
316
317 pub fn is_header_allowed(&self, header_name: &str, header_value: &str) -> AclClassification {
321 if let Some(allowed_value) = self.allowed_headers.get(header_name) {
322 if allowed_value.as_deref() == Some(header_value) || allowed_value.is_none() {
323 AclClassification::AllowedUserAcl
324 } else {
325 AclClassification::DeniedUserAcl
326 }
327 } else if let Some(denied_value) = self.denied_headers.get(header_name) {
328 if denied_value.as_deref() == Some(header_value) || denied_value.is_none() {
329 AclClassification::DeniedUserAcl
330 } else {
331 AclClassification::AllowedUserAcl
332 }
333 } else if self.header_acl_default {
334 AclClassification::AllowedDefault
335 } else {
336 AclClassification::DeniedDefault
337 }
338 }
339
340 pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
344 if self.allowed_url_paths_router.at(url_path).is_ok() {
345 AclClassification::AllowedUserAcl
346 } else if self.denied_url_paths_router.at(url_path).is_ok() {
347 AclClassification::DeniedUserAcl
348 } else if self.url_path_acl_default {
349 AclClassification::AllowedDefault
350 } else {
351 AclClassification::DeniedDefault
352 }
353 }
354
355 pub fn is_valid<'h>(
361 &self,
362 scheme: &str,
363 authority: &Authority,
364 headers: impl Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h,
365 body: Option<&[u8]>,
366 ) -> AclClassification {
367 if let Some(validate_fn) = &self.validate_fn {
368 validate_fn(scheme, authority, Box::new(headers), body)
369 } else {
370 AclClassification::AllowedDefault
371 }
372 }
373
374 fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
376 ranges.iter().any(|range| range.contains(ip))
377 }
378
379 fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
381 ranges.iter().any(|range| range.contains(&port))
382 }
383}
384
385#[non_exhaustive]
392#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
393pub enum AclClassification {
394 AllowedUserAcl,
396 AllowedDefault,
398 DeniedUserAcl,
400 DeniedDefault,
402 Denied(String),
407 DeniedNotGlobal,
409}
410
411impl std::fmt::Display for AclClassification {
412 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
413 match self {
414 AclClassification::AllowedUserAcl => {
415 write!(f, "The entity is allowed according to the allowed ACL.")
416 }
417 AclClassification::AllowedDefault => write!(
418 f,
419 "The entity is allowed because the default is to allow if no ACL match is found."
420 ),
421 AclClassification::DeniedUserAcl => {
422 write!(f, "The entity is denied according to the denied ACL.")
423 }
424 AclClassification::DeniedNotGlobal => {
425 write!(f, "The ip is denied because it is not global.")
426 }
427 AclClassification::DeniedDefault => write!(
428 f,
429 "The entity is denied because the default is to deny if no ACL match is found."
430 ),
431 AclClassification::Denied(reason) => {
432 write!(f, "The entity is denied because {reason}.")
433 }
434 }
435 }
436}
437
438impl AclClassification {
439 pub fn is_allowed(&self) -> bool {
441 matches!(
442 self,
443 AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
444 )
445 }
446
447 pub fn is_denied(&self) -> bool {
449 matches!(
450 self,
451 AclClassification::DeniedUserAcl
452 | AclClassification::Denied(_)
453 | AclClassification::DeniedDefault
454 | AclClassification::DeniedNotGlobal
455 )
456 }
457}
458
459#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
461#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
462pub enum HttpRequestMethod {
463 CONNECT,
465 DELETE,
467 GET,
469 HEAD,
471 OPTIONS,
473 PATCH,
475 POST,
477 PUT,
479 TRACE,
481 OTHER(Box<str>),
483}
484
485impl From<&str> for HttpRequestMethod {
486 fn from(method: &str) -> Self {
487 match method {
488 "CONNECT" => HttpRequestMethod::CONNECT,
489 "DELETE" => HttpRequestMethod::DELETE,
490 "GET" => HttpRequestMethod::GET,
491 "HEAD" => HttpRequestMethod::HEAD,
492 "OPTIONS" => HttpRequestMethod::OPTIONS,
493 "PATCH" => HttpRequestMethod::PATCH,
494 "POST" => HttpRequestMethod::POST,
495 "PUT" => HttpRequestMethod::PUT,
496 "TRACE" => HttpRequestMethod::TRACE,
497 _ => HttpRequestMethod::OTHER(method.into()),
498 }
499 }
500}
501
502impl HttpRequestMethod {
503 pub fn as_str(&self) -> &str {
505 match self {
506 HttpRequestMethod::CONNECT => "CONNECT",
507 HttpRequestMethod::DELETE => "DELETE",
508 HttpRequestMethod::GET => "GET",
509 HttpRequestMethod::HEAD => "HEAD",
510 HttpRequestMethod::OPTIONS => "OPTIONS",
511 HttpRequestMethod::PATCH => "PATCH",
512 HttpRequestMethod::POST => "POST",
513 HttpRequestMethod::PUT => "PUT",
514 HttpRequestMethod::TRACE => "TRACE",
515 HttpRequestMethod::OTHER(other) => other,
516 }
517 }
518}
519
520#[derive(Default, Clone)]
535#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
536pub struct HttpAclBuilder {
537 allow_http: bool,
538 allow_https: bool,
539 allowed_methods: Vec<HttpRequestMethod>,
540 denied_methods: Vec<HttpRequestMethod>,
541 allowed_hosts: Vec<String>,
542 denied_hosts: Vec<String>,
543 #[cfg_attr(feature = "serde", serde(skip))]
544 allowed_host_patterns: Vec<HostPattern>,
545 #[cfg_attr(feature = "serde", serde(skip))]
546 denied_host_patterns: Vec<HostPattern>,
547 allowed_port_ranges: Vec<RangeInclusive<u16>>,
548 denied_port_ranges: Vec<RangeInclusive<u16>>,
549 allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
550 denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
551 static_dns_mapping: HashMap<String, SocketAddr>,
552 trusted_static_dns_mapping: HashMap<String, SocketAddr>,
553 allowed_headers: HashMap<String, Option<String>>,
554 denied_headers: HashMap<String, Option<String>>,
555 allowed_url_paths: Vec<String>,
556 #[cfg_attr(feature = "serde", serde(skip))]
557 allowed_url_paths_router: Router<()>,
558 denied_url_paths: Vec<String>,
559 #[cfg_attr(feature = "serde", serde(skip))]
560 denied_url_paths_router: Router<()>,
561 allow_non_global_ip_ranges: bool,
562 method_acl_default: bool,
563 host_acl_default: bool,
564 port_acl_default: bool,
565 ip_acl_default: bool,
566 header_acl_default: bool,
567 url_path_acl_default: bool,
568}
569
570impl std::fmt::Debug for HttpAclBuilder {
571 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
572 f.debug_struct("HttpAclBuilder")
573 .field("allow_http", &self.allow_http)
574 .field("allow_https", &self.allow_https)
575 .field("allowed_methods", &self.allowed_methods)
576 .field("denied_methods", &self.denied_methods)
577 .field("allowed_hosts", &self.allowed_hosts)
578 .field("denied_hosts", &self.denied_hosts)
579 .field("allowed_port_ranges", &self.allowed_port_ranges)
580 .field("denied_port_ranges", &self.denied_port_ranges)
581 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
582 .field("denied_ip_ranges", &self.denied_ip_ranges)
583 .field("static_dns_mapping", &self.static_dns_mapping)
584 .field(
585 "trusted_static_dns_mapping",
586 &self.trusted_static_dns_mapping,
587 )
588 .field("allowed_headers", &self.allowed_headers)
589 .field("denied_headers", &self.denied_headers)
590 .field("allowed_url_paths", &self.allowed_url_paths)
591 .field("denied_url_paths", &self.denied_url_paths)
592 .field(
593 "allow_non_global_ip_ranges",
594 &self.allow_non_global_ip_ranges,
595 )
596 .field("method_acl_default", &self.method_acl_default)
597 .field("host_acl_default", &self.host_acl_default)
598 .field("port_acl_default", &self.port_acl_default)
599 .field("ip_acl_default", &self.ip_acl_default)
600 .field("header_acl_default", &self.header_acl_default)
601 .field("url_path_acl_default", &self.url_path_acl_default)
602 .finish()
603 }
604}
605
606impl PartialEq for HttpAclBuilder {
607 fn eq(&self, other: &Self) -> bool {
608 self.allow_http == other.allow_http
609 && self.allow_https == other.allow_https
610 && self.allowed_methods == other.allowed_methods
611 && self.denied_methods == other.denied_methods
612 && self.allowed_hosts == other.allowed_hosts
613 && self.denied_hosts == other.denied_hosts
614 && self.allowed_port_ranges == other.allowed_port_ranges
615 && self.denied_port_ranges == other.denied_port_ranges
616 && self.allowed_ip_ranges == other.allowed_ip_ranges
617 && self.denied_ip_ranges == other.denied_ip_ranges
618 && self.static_dns_mapping == other.static_dns_mapping
619 && self.trusted_static_dns_mapping == other.trusted_static_dns_mapping
620 && self.allowed_headers == other.allowed_headers
621 && self.denied_headers == other.denied_headers
622 && self.allowed_url_paths == other.allowed_url_paths
623 && self.denied_url_paths == other.denied_url_paths
624 && self.allow_non_global_ip_ranges == other.allow_non_global_ip_ranges
625 && self.method_acl_default == other.method_acl_default
626 && self.host_acl_default == other.host_acl_default
627 && self.port_acl_default == other.port_acl_default
628 && self.ip_acl_default == other.ip_acl_default
629 && self.header_acl_default == other.header_acl_default
630 && self.url_path_acl_default == other.url_path_acl_default
631 }
632}
633
634impl HttpAclBuilder {
635 pub fn new() -> Self {
637 Self {
638 allow_http: true,
639 allow_https: true,
640 allowed_methods: vec![
641 HttpRequestMethod::CONNECT,
642 HttpRequestMethod::DELETE,
643 HttpRequestMethod::GET,
644 HttpRequestMethod::HEAD,
645 HttpRequestMethod::OPTIONS,
646 HttpRequestMethod::PATCH,
647 HttpRequestMethod::POST,
648 HttpRequestMethod::PUT,
649 HttpRequestMethod::TRACE,
650 ],
651 denied_methods: Vec::new(),
652 allowed_hosts: Vec::new(),
653 denied_hosts: Vec::new(),
654 allowed_host_patterns: Vec::new(),
655 denied_host_patterns: Vec::new(),
656 allowed_port_ranges: vec![80..=80, 443..=443],
657 denied_port_ranges: Vec::new(),
658 allowed_ip_ranges: Vec::new(),
659 denied_ip_ranges: Vec::new(),
660 allowed_headers: HashMap::new(),
661 denied_headers: HashMap::new(),
662 allowed_url_paths: Vec::new(),
663 allowed_url_paths_router: Router::new(),
664 denied_url_paths: Vec::new(),
665 denied_url_paths_router: Router::new(),
666 allow_non_global_ip_ranges: false,
667 static_dns_mapping: HashMap::new(),
668 trusted_static_dns_mapping: HashMap::new(),
669 method_acl_default: false,
670 host_acl_default: false,
671 port_acl_default: false,
672 ip_acl_default: false,
673 header_acl_default: true,
674 url_path_acl_default: true,
675 }
676 }
677
678 pub fn http(mut self, allow: bool) -> Self {
680 self.allow_http = allow;
681 self
682 }
683
684 pub fn https(mut self, allow: bool) -> Self {
686 self.allow_https = allow;
687 self
688 }
689
690 pub fn non_global_ip_ranges(mut self, allow: bool) -> Self {
694 self.allow_non_global_ip_ranges = allow;
695 self
696 }
697
698 pub fn method_acl_default(mut self, allow: bool) -> Self {
700 self.method_acl_default = allow;
701 self
702 }
703
704 pub fn host_acl_default(mut self, allow: bool) -> Self {
706 self.host_acl_default = allow;
707 self
708 }
709
710 pub fn port_acl_default(mut self, allow: bool) -> Self {
712 self.port_acl_default = allow;
713 self
714 }
715
716 pub fn ip_acl_default(mut self, allow: bool) -> Self {
718 self.ip_acl_default = allow;
719 self
720 }
721
722 pub fn header_acl_default(mut self, allow: bool) -> Self {
724 self.header_acl_default = allow;
725 self
726 }
727
728 pub fn url_path_acl_default(mut self, allow: bool) -> Self {
730 self.url_path_acl_default = allow;
731 self
732 }
733
734 pub fn add_allowed_method(
738 mut self,
739 method: impl Into<HttpRequestMethod>,
740 ) -> Result<Self, AddError> {
741 let method = method.into();
742 if self.denied_methods.contains(&method) {
743 Err(AddError::AlreadyDeniedMethod(method))
744 } else if self.allowed_methods.contains(&method) {
745 Err(AddError::AlreadyAllowedMethod(method))
746 } else {
747 self.allowed_methods.push(method);
748 Ok(self)
749 }
750 }
751
752 pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
756 let method = method.into();
757 self.allowed_methods.retain(|m| m != &method);
758 self
759 }
760
761 pub fn allowed_methods(
765 mut self,
766 methods: Vec<impl Into<HttpRequestMethod>>,
767 ) -> Result<Self, AddError> {
768 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
769
770 for method in &methods {
771 if self.denied_methods.contains(method) {
772 return Err(AddError::AlreadyDeniedMethod(method.clone()));
773 }
774 }
775 self.allowed_methods = methods;
776 Ok(self)
777 }
778
779 pub fn clear_allowed_methods(mut self) -> Self {
781 self.allowed_methods.clear();
782 self
783 }
784
785 pub fn add_denied_method(
789 mut self,
790 method: impl Into<HttpRequestMethod>,
791 ) -> Result<Self, AddError> {
792 let method = method.into();
793 if self.allowed_methods.contains(&method) {
794 Err(AddError::AlreadyAllowedMethod(method))
795 } else if self.denied_methods.contains(&method) {
796 Err(AddError::AlreadyDeniedMethod(method))
797 } else {
798 self.denied_methods.push(method);
799 Ok(self)
800 }
801 }
802
803 pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
807 let method = method.into();
808 self.denied_methods.retain(|m| m != &method);
809 self
810 }
811
812 pub fn denied_methods(
816 mut self,
817 methods: Vec<impl Into<HttpRequestMethod>>,
818 ) -> Result<Self, AddError> {
819 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
820
821 for method in &methods {
822 if self.allowed_methods.contains(method) {
823 return Err(AddError::AlreadyAllowedMethod(method.clone()));
824 }
825 }
826 self.denied_methods = methods;
827 Ok(self)
828 }
829
830 pub fn clear_denied_methods(mut self) -> Self {
832 self.denied_methods.clear();
833 self
834 }
835
836 pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
850 let pattern = Self::validate_host_or_pattern(&host)?;
851
852 if self.denied_hosts.contains(&host) {
853 return Err(AddError::AlreadyDeniedHost(host));
854 }
855 if self.allowed_hosts.contains(&host) {
856 return Err(AddError::AlreadyAllowedHost(host));
857 }
858
859 if let Some(pattern) = pattern {
860 self.allowed_host_patterns.push(pattern);
861 }
862 self.allowed_hosts.push(host);
863 Ok(self)
864 }
865
866 pub fn remove_allowed_host(mut self, host: String) -> Self {
870 self.allowed_hosts.retain(|h| h != &host);
871 self.allowed_host_patterns = Self::compile_host_patterns(&self.allowed_hosts);
872 self
873 }
874
875 pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
881 let mut patterns = Vec::new();
882 for host in &hosts {
883 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
884 patterns.push(pattern);
885 }
886 if self.denied_hosts.contains(host) {
887 return Err(AddError::AlreadyDeniedHost(host.clone()));
888 }
889 }
890 self.allowed_host_patterns = patterns;
891 self.allowed_hosts = hosts;
892 Ok(self)
893 }
894
895 pub fn clear_allowed_hosts(mut self) -> Self {
897 self.allowed_hosts.clear();
898 self.allowed_host_patterns.clear();
899 self
900 }
901
902 pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
908 let pattern = Self::validate_host_or_pattern(&host)?;
909
910 if self.allowed_hosts.contains(&host) {
911 return Err(AddError::AlreadyAllowedHost(host));
912 }
913 if self.denied_hosts.contains(&host) {
914 return Err(AddError::AlreadyDeniedHost(host));
915 }
916
917 if let Some(pattern) = pattern {
918 self.denied_host_patterns.push(pattern);
919 }
920 self.denied_hosts.push(host);
921 Ok(self)
922 }
923
924 pub fn remove_denied_host(mut self, host: String) -> Self {
928 self.denied_hosts.retain(|h| h != &host);
929 self.denied_host_patterns = Self::compile_host_patterns(&self.denied_hosts);
930 self
931 }
932
933 pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
939 let mut patterns = Vec::new();
940 for host in &hosts {
941 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
942 patterns.push(pattern);
943 }
944 if self.allowed_hosts.contains(host) {
945 return Err(AddError::AlreadyAllowedHost(host.clone()));
946 }
947 }
948 self.denied_host_patterns = patterns;
949 self.denied_hosts = hosts;
950 Ok(self)
951 }
952
953 pub fn clear_denied_hosts(mut self) -> Self {
955 self.denied_hosts.clear();
956 self.denied_host_patterns.clear();
957 self
958 }
959
960 fn validate_host_or_pattern(host: &str) -> Result<Option<HostPattern>, AddError> {
963 if is_wildcard_host(host) {
964 match HostPattern::parse(host) {
965 Some(pattern) => Ok(Some(pattern)),
966 None => Err(AddError::InvalidEntity(host.to_string())),
967 }
968 } else if utils::authority::is_valid_host(host) {
969 Ok(None)
970 } else {
971 Err(AddError::InvalidEntity(host.to_string()))
972 }
973 }
974
975 fn compile_host_patterns(hosts: &[String]) -> Vec<HostPattern> {
977 hosts
978 .iter()
979 .filter(|h| is_wildcard_host(h))
980 .filter_map(|h| HostPattern::parse(h))
981 .collect()
982 }
983
984 pub fn add_allowed_port_range(
986 mut self,
987 port_range: RangeInclusive<u16>,
988 ) -> Result<Self, AddError> {
989 if self.denied_port_ranges.contains(&port_range) {
990 Err(AddError::AlreadyDeniedPortRange(port_range))
991 } else if self.allowed_port_ranges.contains(&port_range) {
992 Err(AddError::AlreadyAllowedPortRange(port_range))
993 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
994 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
995 {
996 Err(AddError::Overlaps(format!("{port_range:?}")))
997 } else {
998 self.allowed_port_ranges.push(port_range);
999 Ok(self)
1000 }
1001 }
1002
1003 pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1005 self.allowed_port_ranges.retain(|p| p != &port_range);
1006 self
1007 }
1008
1009 pub fn allowed_port_ranges(
1011 mut self,
1012 port_ranges: Vec<RangeInclusive<u16>>,
1013 ) -> Result<Self, AddError> {
1014 for (i, port_range) in port_ranges.iter().enumerate() {
1015 if self.denied_port_ranges.contains(port_range) {
1016 return Err(AddError::AlreadyDeniedPortRange(port_range.clone()));
1017 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1018 || utils::range_overlaps(&self.denied_port_ranges, port_range, None)
1019 {
1020 return Err(AddError::Overlaps(format!("{port_range:?}")));
1021 }
1022 }
1023 self.allowed_port_ranges = port_ranges;
1024 Ok(self)
1025 }
1026
1027 pub fn clear_allowed_port_ranges(mut self) -> Self {
1029 self.allowed_port_ranges.clear();
1030 self
1031 }
1032
1033 pub fn add_denied_port_range(
1035 mut self,
1036 port_range: RangeInclusive<u16>,
1037 ) -> Result<Self, AddError> {
1038 if self.allowed_port_ranges.contains(&port_range) {
1039 Err(AddError::AlreadyAllowedPortRange(port_range))
1040 } else if self.denied_port_ranges.contains(&port_range) {
1041 Err(AddError::AlreadyDeniedPortRange(port_range))
1042 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
1043 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
1044 {
1045 Err(AddError::Overlaps(format!("{port_range:?}")))
1046 } else {
1047 self.denied_port_ranges.push(port_range);
1048 Ok(self)
1049 }
1050 }
1051
1052 pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1054 self.denied_port_ranges.retain(|p| p != &port_range);
1055 self
1056 }
1057
1058 pub fn denied_port_ranges(
1060 mut self,
1061 port_ranges: Vec<RangeInclusive<u16>>,
1062 ) -> Result<Self, AddError> {
1063 for (i, port_range) in port_ranges.iter().enumerate() {
1064 if self.allowed_port_ranges.contains(port_range) {
1065 return Err(AddError::AlreadyAllowedPortRange(port_range.clone()));
1066 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1067 || utils::range_overlaps(&self.allowed_port_ranges, port_range, None)
1068 {
1069 return Err(AddError::Overlaps(format!("{port_range:?}")));
1070 }
1071 }
1072 self.denied_port_ranges = port_ranges;
1073 Ok(self)
1074 }
1075
1076 pub fn clear_denied_port_ranges(mut self) -> Self {
1078 self.denied_port_ranges.clear();
1079 self
1080 }
1081
1082 pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1084 let ip_range = ip_range
1085 .into_range()
1086 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1087 if self.denied_ip_ranges.contains(&ip_range) {
1088 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1089 } else if self.allowed_ip_ranges.contains(&ip_range) {
1090 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1091 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1092 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1093 {
1094 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1095 }
1096 self.allowed_ip_ranges.push(ip_range);
1097 Ok(self)
1098 }
1099
1100 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
1102 mut self,
1103 ip_range: Ip,
1104 ) -> Result<Self, AddError> {
1105 let ip_range = ip_range
1106 .into_range()
1107 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1108 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
1109 Ok(self)
1110 }
1111
1112 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
1114 mut self,
1115 ip_ranges: Vec<Ip>,
1116 ) -> Result<Self, AddError> {
1117 let ip_ranges = ip_ranges
1118 .into_iter()
1119 .map(|ip| ip.into_range())
1120 .collect::<Option<Vec<_>>>()
1121 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1122 for (i, ip_range) in ip_ranges.iter().enumerate() {
1123 if self.denied_ip_ranges.contains(ip_range) {
1124 return Err(AddError::AlreadyDeniedIpRange(ip_range.clone()));
1125 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1126 || utils::range_overlaps(&self.denied_ip_ranges, ip_range, None)
1127 {
1128 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1129 }
1130 }
1131 self.allowed_ip_ranges = ip_ranges;
1132 Ok(self)
1133 }
1134
1135 pub fn clear_allowed_ip_ranges(mut self) -> Self {
1137 self.allowed_ip_ranges.clear();
1138 self
1139 }
1140
1141 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1143 let ip_range = ip_range
1144 .into_range()
1145 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1146 if self.allowed_ip_ranges.contains(&ip_range) {
1147 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1148 } else if self.denied_ip_ranges.contains(&ip_range) {
1149 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1150 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1151 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1152 {
1153 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1154 }
1155 self.denied_ip_ranges.push(ip_range);
1156 Ok(self)
1157 }
1158
1159 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
1161 mut self,
1162 ip_range: Ip,
1163 ) -> Result<Self, AddError> {
1164 let ip_range = ip_range
1165 .into_range()
1166 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1167 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
1168 Ok(self)
1169 }
1170
1171 pub fn denied_ip_ranges<Ip: IntoIpRange>(
1173 mut self,
1174 ip_ranges: Vec<Ip>,
1175 ) -> Result<Self, AddError> {
1176 let ip_ranges = ip_ranges
1177 .into_iter()
1178 .map(|ip| ip.into_range())
1179 .collect::<Option<Vec<_>>>()
1180 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1181 for (i, ip_range) in ip_ranges.iter().enumerate() {
1182 if self.allowed_ip_ranges.contains(ip_range) {
1183 return Err(AddError::AlreadyAllowedIpRange(ip_range.clone()));
1184 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1185 || utils::range_overlaps(&self.allowed_ip_ranges, ip_range, None)
1186 {
1187 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1188 }
1189 }
1190 self.denied_ip_ranges = ip_ranges;
1191 Ok(self)
1192 }
1193
1194 pub fn clear_denied_ip_ranges(mut self) -> Self {
1196 self.denied_ip_ranges.clear();
1197 self
1198 }
1199
1200 pub fn add_static_dns_mapping(
1208 mut self,
1209 host: String,
1210 sock_addr: SocketAddr,
1211 ) -> Result<Self, AddError> {
1212 if !utils::authority::is_valid_host(&host) {
1213 return Err(AddError::InvalidEntity(host));
1214 }
1215 if self.trusted_static_dns_mapping.contains_key(&host) {
1216 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1217 host, sock_addr,
1218 ));
1219 }
1220 if let Entry::Vacant(e) = self.static_dns_mapping.entry(host.clone()) {
1221 e.insert(sock_addr);
1222 Ok(self)
1223 } else {
1224 Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr))
1225 }
1226 }
1227
1228 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
1232 self.static_dns_mapping.remove(host);
1233 self
1234 }
1235
1236 pub fn static_dns_mappings(
1240 mut self,
1241 mappings: HashMap<String, SocketAddr>,
1242 ) -> Result<Self, AddError> {
1243 for (host, ip) in &mappings {
1244 if !utils::authority::is_valid_host(host) {
1245 return Err(AddError::InvalidEntity(host.clone()));
1246 }
1247 if self.trusted_static_dns_mapping.contains_key(host) {
1248 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1249 host.clone(),
1250 *ip,
1251 ));
1252 }
1253 if self.static_dns_mapping.contains_key(host) {
1254 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1255 }
1256 self.static_dns_mapping.insert(host.to_string(), *ip);
1257 }
1258 Ok(self)
1259 }
1260
1261 pub fn clear_static_dns_mappings(mut self) -> Self {
1263 self.static_dns_mapping.clear();
1264 self
1265 }
1266
1267 pub fn add_trusted_static_dns_mapping(
1276 mut self,
1277 host: String,
1278 sock_addr: SocketAddr,
1279 ) -> Result<Self, AddError> {
1280 if !utils::authority::is_valid_host(&host) {
1281 return Err(AddError::InvalidEntity(host));
1282 }
1283 if self.static_dns_mapping.contains_key(&host) {
1284 return Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr));
1285 }
1286 if let Entry::Vacant(e) = self.trusted_static_dns_mapping.entry(host.clone()) {
1287 e.insert(sock_addr);
1288 Ok(self)
1289 } else {
1290 Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1291 host, sock_addr,
1292 ))
1293 }
1294 }
1295
1296 pub fn remove_trusted_static_dns_mapping(mut self, host: &str) -> Self {
1300 self.trusted_static_dns_mapping.remove(host);
1301 self
1302 }
1303
1304 pub fn trusted_static_dns_mappings(
1308 mut self,
1309 mappings: HashMap<String, SocketAddr>,
1310 ) -> Result<Self, AddError> {
1311 for (host, ip) in &mappings {
1312 if !utils::authority::is_valid_host(host) {
1313 return Err(AddError::InvalidEntity(host.clone()));
1314 }
1315 if self.static_dns_mapping.contains_key(host) {
1316 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1317 }
1318 if self.trusted_static_dns_mapping.contains_key(host) {
1319 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1320 host.clone(),
1321 *ip,
1322 ));
1323 }
1324 self.trusted_static_dns_mapping
1325 .insert(host.to_string(), *ip);
1326 }
1327 Ok(self)
1328 }
1329
1330 pub fn clear_trusted_static_dns_mappings(mut self) -> Self {
1332 self.trusted_static_dns_mapping.clear();
1333 self
1334 }
1335
1336 pub fn add_allowed_header(
1342 mut self,
1343 header: String,
1344 value: Option<String>,
1345 ) -> Result<Self, AddError> {
1346 if self.denied_headers.contains_key(&header) {
1347 Err(AddError::AlreadyDeniedHeader(header, value.clone()))
1348 } else if let Entry::Vacant(e) = self.allowed_headers.entry(header.clone()) {
1349 e.insert(value);
1350 Ok(self)
1351 } else {
1352 Err(AddError::AlreadyAllowedHeader(header, value))
1353 }
1354 }
1355
1356 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1360 self.allowed_headers.remove(header);
1361 self
1362 }
1363
1364 pub fn allowed_headers(
1368 mut self,
1369 headers: HashMap<String, Option<String>>,
1370 ) -> Result<Self, AddError> {
1371 for (header, value) in &headers {
1372 if self.denied_headers.contains_key(header) {
1373 return Err(AddError::AlreadyDeniedHeader(header.clone(), value.clone()));
1374 }
1375 }
1376 self.allowed_headers = headers;
1377 Ok(self)
1378 }
1379
1380 pub fn clear_allowed_headers(mut self) -> Self {
1382 self.allowed_headers.clear();
1383 self
1384 }
1385
1386 pub fn add_denied_header(
1392 mut self,
1393 header: String,
1394 value: Option<String>,
1395 ) -> Result<Self, AddError> {
1396 if self.allowed_headers.contains_key(&header) {
1397 Err(AddError::AlreadyAllowedHeader(header, value.clone()))
1398 } else if let Entry::Vacant(e) = self.denied_headers.entry(header.clone()) {
1399 e.insert(value);
1400 Ok(self)
1401 } else {
1402 Err(AddError::AlreadyDeniedHeader(header, value))
1403 }
1404 }
1405
1406 pub fn remove_denied_header(mut self, header: &str) -> Self {
1410 self.denied_headers.remove(header);
1411 self
1412 }
1413
1414 pub fn denied_headers(
1418 mut self,
1419 headers: HashMap<String, Option<String>>,
1420 ) -> Result<Self, AddError> {
1421 for (header, value) in &headers {
1422 if self.allowed_headers.contains_key(header) {
1423 return Err(AddError::AlreadyAllowedHeader(
1424 header.clone(),
1425 value.clone(),
1426 ));
1427 }
1428 }
1429 self.denied_headers = headers;
1430 Ok(self)
1431 }
1432
1433 pub fn clear_denied_headers(mut self) -> Self {
1435 self.denied_headers.clear();
1436 self
1437 }
1438
1439 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1443 if self.denied_url_paths.contains(&url_path)
1444 || self.denied_url_paths_router.at(&url_path).is_ok()
1445 {
1446 Err(AddError::AlreadyDeniedUrlPath(url_path))
1447 } else if self.allowed_url_paths.contains(&url_path)
1448 || self.allowed_url_paths_router.at(&url_path).is_ok()
1449 {
1450 Err(AddError::AlreadyAllowedUrlPath(url_path))
1451 } else {
1452 self.allowed_url_paths.push(url_path.clone());
1453 self.allowed_url_paths_router
1454 .insert(url_path, ())
1455 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1456 Ok(self)
1457 }
1458 }
1459
1460 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1464 self.allowed_url_paths.retain(|p| p != url_path);
1465 self.allowed_url_paths_router = {
1466 let mut router = Router::new();
1467 for url_path in &self.allowed_url_paths {
1468 router
1469 .insert(url_path.clone(), ())
1470 .expect("failed to insert url path");
1471 }
1472 router
1473 };
1474 self
1475 }
1476
1477 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1481 for url_path in &url_paths {
1482 if self.denied_url_paths.contains(url_path)
1483 || self.denied_url_paths_router.at(url_path).is_ok()
1484 {
1485 return Err(AddError::AlreadyDeniedUrlPath(url_path.clone()));
1486 }
1487 }
1488 self.allowed_url_paths_router = Router::new();
1489 for url_path in &url_paths {
1490 self.allowed_url_paths_router
1491 .insert(url_path.clone(), ())
1492 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1493 }
1494 self.allowed_url_paths = url_paths;
1495 Ok(self)
1496 }
1497
1498 pub fn clear_allowed_url_paths(mut self) -> Self {
1500 self.allowed_url_paths.clear();
1501 self.allowed_url_paths_router = Router::new();
1502 self
1503 }
1504
1505 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1509 if self.allowed_url_paths.contains(&url_path)
1510 || self.allowed_url_paths_router.at(&url_path).is_ok()
1511 {
1512 Err(AddError::AlreadyAllowedUrlPath(url_path))
1513 } else if self.denied_url_paths.contains(&url_path)
1514 || self.denied_url_paths_router.at(&url_path).is_ok()
1515 {
1516 Err(AddError::AlreadyDeniedUrlPath(url_path))
1517 } else {
1518 self.denied_url_paths.push(url_path.clone());
1519 self.denied_url_paths_router
1520 .insert(url_path, ())
1521 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1522 Ok(self)
1523 }
1524 }
1525
1526 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1530 self.denied_url_paths.retain(|p| p != url_path);
1531 self.denied_url_paths_router = {
1532 let mut router = Router::new();
1533 for url_path in &self.denied_url_paths {
1534 router
1535 .insert(url_path.clone(), ())
1536 .expect("failed to insert url path");
1537 }
1538 router
1539 };
1540 self
1541 }
1542
1543 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1547 for url_path in &url_paths {
1548 if self.allowed_url_paths.contains(url_path)
1549 || self.allowed_url_paths_router.at(url_path).is_ok()
1550 {
1551 return Err(AddError::AlreadyAllowedUrlPath(url_path.clone()));
1552 }
1553 }
1554 self.denied_url_paths_router = Router::new();
1555 for url_path in &url_paths {
1556 self.denied_url_paths_router
1557 .insert(url_path.clone(), ())
1558 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1559 }
1560 self.denied_url_paths = url_paths;
1561 Ok(self)
1562 }
1563
1564 pub fn clear_denied_url_paths(mut self) -> Self {
1566 self.denied_url_paths.clear();
1567 self.denied_url_paths_router = Router::new();
1568 self
1569 }
1570
1571 pub fn build(self) -> HttpAcl {
1578 self.build_full(None)
1579 }
1580
1581 pub fn build_full(self, validate_fn: Option<ValidateFn>) -> HttpAcl {
1587 HttpAcl {
1588 allow_http: self.allow_http,
1589 allow_https: self.allow_https,
1590 allowed_methods: self.allowed_methods.into_iter().collect(),
1591 denied_methods: self.denied_methods.into_iter().collect(),
1592 allowed_hosts: self
1593 .allowed_hosts
1594 .into_iter()
1595 .filter(|h| !is_wildcard_host(h))
1596 .map(|x| x.into_boxed_str())
1597 .collect(),
1598 denied_hosts: self
1599 .denied_hosts
1600 .into_iter()
1601 .filter(|h| !is_wildcard_host(h))
1602 .map(|x| x.into_boxed_str())
1603 .collect(),
1604 allowed_host_patterns: self.allowed_host_patterns.into_boxed_slice(),
1605 denied_host_patterns: self.denied_host_patterns.into_boxed_slice(),
1606 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1607 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1608 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1609 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1610 allowed_headers: self
1611 .allowed_headers
1612 .into_iter()
1613 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1614 .collect(),
1615 denied_headers: self
1616 .denied_headers
1617 .into_iter()
1618 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1619 .collect(),
1620 allowed_url_paths_router: self.allowed_url_paths_router,
1621 denied_url_paths_router: self.denied_url_paths_router,
1622 static_dns_mapping: self
1623 .static_dns_mapping
1624 .into_iter()
1625 .map(|(k, v)| (k.into_boxed_str(), v))
1626 .collect(),
1627 trusted_static_dns_mapping: self
1628 .trusted_static_dns_mapping
1629 .into_iter()
1630 .map(|(k, v)| (k.into_boxed_str(), v))
1631 .collect(),
1632 validate_fn,
1633 allow_non_global_ip_ranges: self.allow_non_global_ip_ranges,
1634 method_acl_default: self.method_acl_default,
1635 host_acl_default: self.host_acl_default,
1636 port_acl_default: self.port_acl_default,
1637 ip_acl_default: self.ip_acl_default,
1638 header_acl_default: self.header_acl_default,
1639 url_path_acl_default: self.url_path_acl_default,
1640 }
1641 }
1642
1643 pub fn try_build_full(mut self, validate_fn: Option<ValidateFn>) -> Result<HttpAcl, AddError> {
1660 if !utils::has_unique_elements(&self.allowed_methods) {
1661 return Err(AddError::NotUnique(
1662 "Allowed methods must be unique.".to_string(),
1663 ));
1664 }
1665 for method in &self.allowed_methods {
1666 if self.denied_methods.contains(method) {
1667 return Err(AddError::BothAllowedAndDenied(format!(
1668 "Method `{}`",
1669 method.as_str()
1670 )));
1671 }
1672 }
1673 if !utils::has_unique_elements(&self.denied_methods) {
1674 return Err(AddError::NotUnique(
1675 "Denied methods must be unique.".to_string(),
1676 ));
1677 }
1678 for method in &self.denied_methods {
1679 if self.allowed_methods.contains(method) {
1680 return Err(AddError::BothAllowedAndDenied(format!(
1681 "Method `{}`",
1682 method.as_str()
1683 )));
1684 }
1685 }
1686 if !utils::has_unique_elements(&self.allowed_hosts) {
1687 return Err(AddError::NotUnique(
1688 "Allowed hosts must be unique.".to_string(),
1689 ));
1690 }
1691 for host in &self.allowed_hosts {
1692 if is_wildcard_host(host) {
1693 match HostPattern::parse(host) {
1694 Some(pattern) => {
1695 if !self.allowed_host_patterns.contains(&pattern) {
1696 self.allowed_host_patterns.push(pattern);
1697 }
1698 }
1699 None => return Err(AddError::InvalidEntity(host.to_string())),
1700 }
1701 } else if !utils::authority::is_valid_host(host) {
1702 return Err(AddError::InvalidEntity(host.to_string()));
1703 }
1704 if self.denied_hosts.contains(host) {
1705 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1706 }
1707 }
1708 if !utils::has_unique_elements(&self.denied_hosts) {
1709 return Err(AddError::NotUnique(
1710 "Denied hosts must be unique.".to_string(),
1711 ));
1712 }
1713 for host in &self.denied_hosts {
1714 if is_wildcard_host(host) {
1715 match HostPattern::parse(host) {
1716 Some(pattern) => {
1717 if !self.denied_host_patterns.contains(&pattern) {
1718 self.denied_host_patterns.push(pattern);
1719 }
1720 }
1721 None => return Err(AddError::InvalidEntity(host.to_string())),
1722 }
1723 } else if !utils::authority::is_valid_host(host) {
1724 return Err(AddError::InvalidEntity(host.to_string()));
1725 }
1726 if self.allowed_hosts.contains(host) {
1727 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1728 }
1729 }
1730 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1731 return Err(AddError::NotUnique(
1732 "Allowed port ranges must be unique.".to_string(),
1733 ));
1734 }
1735 if utils::has_overlapping_ranges(&self.allowed_port_ranges) {
1736 return Err(AddError::Overlaps(
1737 "Allowed port ranges must not overlap.".to_string(),
1738 ));
1739 }
1740 for port_range in &self.allowed_port_ranges {
1741 if self.denied_port_ranges.contains(port_range) {
1742 return Err(AddError::BothAllowedAndDenied(format!(
1743 "Port range `{port_range:?}`"
1744 )));
1745 }
1746 }
1747 if !utils::has_unique_elements(&self.denied_port_ranges) {
1748 return Err(AddError::NotUnique(
1749 "Denied port ranges must be unique.".to_string(),
1750 ));
1751 }
1752 if utils::has_overlapping_ranges(&self.denied_port_ranges) {
1753 return Err(AddError::Overlaps(
1754 "Denied port ranges must not overlap.".to_string(),
1755 ));
1756 }
1757 for port_range in &self.denied_port_ranges {
1758 if self.allowed_port_ranges.contains(port_range) {
1759 return Err(AddError::BothAllowedAndDenied(format!(
1760 "Port range `{port_range:?}`"
1761 )));
1762 }
1763 }
1764 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1765 return Err(AddError::NotUnique(
1766 "Allowed IP ranges must be unique.".to_string(),
1767 ));
1768 }
1769 if utils::has_overlapping_ranges(&self.allowed_ip_ranges) {
1770 return Err(AddError::Overlaps(
1771 "Allowed IP ranges must not overlap.".to_string(),
1772 ));
1773 }
1774 for ip_range in &self.allowed_ip_ranges {
1775 if self.denied_ip_ranges.contains(ip_range) {
1776 return Err(AddError::BothAllowedAndDenied(format!(
1777 "IP range `{ip_range:?}`"
1778 )));
1779 }
1780
1781 if (!utils::ip::is_global_ip(ip_range.start())
1782 || !utils::ip::is_global_ip(ip_range.end()))
1783 && !self.allow_non_global_ip_ranges
1784 {
1785 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1786 }
1787 }
1788 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1789 return Err(AddError::NotUnique(
1790 "Denied IP ranges must be unique.".to_string(),
1791 ));
1792 }
1793 if utils::has_overlapping_ranges(&self.denied_ip_ranges) {
1794 return Err(AddError::Overlaps(
1795 "Denied IP ranges must not overlap.".to_string(),
1796 ));
1797 }
1798 for ip_range in &self.denied_ip_ranges {
1799 if self.allowed_ip_ranges.contains(ip_range) {
1800 return Err(AddError::BothAllowedAndDenied(format!(
1801 "IP range `{ip_range:?}`"
1802 )));
1803 }
1804
1805 if (!utils::ip::is_global_ip(ip_range.start())
1806 || !utils::ip::is_global_ip(ip_range.end()))
1807 && !self.allow_non_global_ip_ranges
1808 {
1809 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1810 }
1811 }
1812 if !utils::has_unique_elements(&self.static_dns_mapping) {
1813 return Err(AddError::NotUnique(
1814 "Static DNS mapping must be unique.".to_string(),
1815 ));
1816 }
1817 for (host, addr) in &self.static_dns_mapping {
1818 if !utils::authority::is_valid_host(host) {
1819 return Err(AddError::InvalidEntity(host.to_string()));
1820 }
1821 if self.trusted_static_dns_mapping.contains_key(host) {
1822 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1823 host.to_string(),
1824 *addr,
1825 ));
1826 }
1827 }
1828 if !utils::has_unique_elements(&self.trusted_static_dns_mapping) {
1829 return Err(AddError::NotUnique(
1830 "Trusted static DNS mapping must be unique.".to_string(),
1831 ));
1832 }
1833 for host in self.trusted_static_dns_mapping.keys() {
1834 if !utils::authority::is_valid_host(host) {
1835 return Err(AddError::InvalidEntity(host.to_string()));
1836 }
1837 }
1838 if !utils::has_unique_elements(&self.allowed_url_paths) {
1839 return Err(AddError::NotUnique(
1840 "Allowed URL paths must be unique.".to_string(),
1841 ));
1842 }
1843 for url_path in &self.allowed_url_paths {
1844 if self.denied_url_paths.contains(url_path)
1845 || self.denied_url_paths_router.at(url_path).is_ok()
1846 {
1847 return Err(AddError::BothAllowedAndDenied(format!(
1848 "URL path `{url_path}`"
1849 )));
1850 } else if self.allowed_url_paths_router.at(url_path).is_err() {
1851 self.allowed_url_paths_router
1852 .insert(url_path.clone(), ())
1853 .map_err(|_| {
1854 AddError::InvalidEntity(format!(
1855 "Failed to insert allowed URL path `{url_path}`."
1856 ))
1857 })?;
1858 }
1859 }
1860 if !utils::has_unique_elements(&self.denied_url_paths) {
1861 return Err(AddError::NotUnique(
1862 "Denied URL paths must be unique.".to_string(),
1863 ));
1864 }
1865 for url_path in &self.denied_url_paths {
1866 if self.allowed_url_paths.contains(url_path)
1867 || self.allowed_url_paths_router.at(url_path).is_ok()
1868 {
1869 return Err(AddError::BothAllowedAndDenied(format!(
1870 "URL path `{url_path}`"
1871 )));
1872 } else if self.denied_url_paths_router.at(url_path).is_err() {
1873 self.denied_url_paths_router
1874 .insert(url_path.clone(), ())
1875 .map_err(|_| {
1876 AddError::InvalidEntity(format!(
1877 "Failed to insert denied URL path `{url_path}`."
1878 ))
1879 })?;
1880 }
1881 }
1882 Ok(self.build_full(validate_fn))
1883 }
1884
1885 pub fn try_build(self) -> Result<HttpAcl, AddError> {
1889 self.try_build_full(None)
1890 }
1891}