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 mutation::{ModifyRequestFn, ModifyResponseFn, RequestMutation, ResponseMutation},
30 utils::{
31 self, IntoIpRange,
32 authority::Authority,
33 host_pattern::{HostPattern, is_wildcard_host},
34 },
35};
36
37pub type ValidateFn = Arc<
50 dyn for<'h> Fn(
51 &str,
52 &Authority,
53 Box<dyn Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h>,
54 Option<&[u8]>,
55 ) -> AclClassification
56 + Send
57 + Sync,
58>;
59
60#[derive(Clone)]
61pub struct HttpAcl {
69 allow_http: bool,
70 allow_https: bool,
71 allowed_methods: HashSet<HttpRequestMethod>,
72 denied_methods: HashSet<HttpRequestMethod>,
73 allowed_hosts: HashSet<Box<str>>,
74 denied_hosts: HashSet<Box<str>>,
75 allowed_host_patterns: Box<[HostPattern]>,
76 denied_host_patterns: Box<[HostPattern]>,
77 allowed_port_ranges: Box<[RangeInclusive<u16>]>,
78 denied_port_ranges: Box<[RangeInclusive<u16>]>,
79 allowed_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
80 denied_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
81 static_dns_mapping: HashMap<Box<str>, SocketAddr>,
82 trusted_static_dns_mapping: HashMap<Box<str>, SocketAddr>,
83 allowed_headers: HashMap<Box<str>, Option<Box<str>>>,
84 denied_headers: HashMap<Box<str>, Option<Box<str>>>,
85 allowed_url_paths_router: Router<()>,
86 denied_url_paths_router: Router<()>,
87 validate_fn: Option<ValidateFn>,
88 modify_request_fn: Option<ModifyRequestFn>,
89 modify_response_fn: Option<ModifyResponseFn>,
90 allow_non_global_ip_ranges: bool,
91 method_acl_default: bool,
92 host_acl_default: bool,
93 port_acl_default: bool,
94 ip_acl_default: bool,
95 header_acl_default: bool,
96 url_path_acl_default: bool,
97}
98
99impl std::fmt::Debug for HttpAcl {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 f.debug_struct("HttpAcl")
102 .field("allow_http", &self.allow_http)
103 .field("allow_https", &self.allow_https)
104 .field("allowed_methods", &self.allowed_methods)
105 .field("denied_methods", &self.denied_methods)
106 .field("allowed_hosts", &self.allowed_hosts)
107 .field("denied_hosts", &self.denied_hosts)
108 .field("allowed_port_ranges", &self.allowed_port_ranges)
109 .field("denied_port_ranges", &self.denied_port_ranges)
110 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
111 .field("denied_ip_ranges", &self.denied_ip_ranges)
112 .field("static_dns_mapping", &self.static_dns_mapping)
113 .field(
114 "trusted_static_dns_mapping",
115 &self.trusted_static_dns_mapping,
116 )
117 .field("allowed_headers", &self.allowed_headers)
118 .field("denied_headers", &self.denied_headers)
119 .field(
120 "allow_non_global_ip_ranges",
121 &self.allow_non_global_ip_ranges,
122 )
123 .field("method_acl_default", &self.method_acl_default)
124 .field("host_acl_default", &self.host_acl_default)
125 .field("port_acl_default", &self.port_acl_default)
126 .field("ip_acl_default", &self.ip_acl_default)
127 .field("header_acl_default", &self.header_acl_default)
128 .field("url_path_acl_default", &self.url_path_acl_default)
129 .finish()
130 }
131}
132
133impl PartialEq for HttpAcl {
134 fn eq(&self, other: &Self) -> bool {
135 self.allow_http == other.allow_http
136 && self.allow_https == other.allow_https
137 && self.allowed_methods == other.allowed_methods
138 && self.denied_methods == other.denied_methods
139 && self.allowed_hosts == other.allowed_hosts
140 && self.denied_hosts == other.denied_hosts
141 && self.allowed_port_ranges == other.allowed_port_ranges
142 && self.denied_port_ranges == other.denied_port_ranges
143 && self.allowed_ip_ranges == other.allowed_ip_ranges
144 && self.denied_ip_ranges == other.denied_ip_ranges
145 && self.static_dns_mapping == other.static_dns_mapping
146 && self.trusted_static_dns_mapping == other.trusted_static_dns_mapping
147 && self.allowed_headers == other.allowed_headers
148 && self.denied_headers == other.denied_headers
149 && self.allow_non_global_ip_ranges == other.allow_non_global_ip_ranges
150 && self.method_acl_default == other.method_acl_default
151 && self.host_acl_default == other.host_acl_default
152 && self.port_acl_default == other.port_acl_default
153 && self.ip_acl_default == other.ip_acl_default
154 && self.header_acl_default == other.header_acl_default
155 && self.url_path_acl_default == other.url_path_acl_default
156 }
157}
158
159impl std::default::Default for HttpAcl {
160 fn default() -> Self {
161 Self {
162 allow_http: true,
163 allow_https: true,
164 allowed_methods: [
165 HttpRequestMethod::CONNECT,
166 HttpRequestMethod::DELETE,
167 HttpRequestMethod::GET,
168 HttpRequestMethod::HEAD,
169 HttpRequestMethod::OPTIONS,
170 HttpRequestMethod::PATCH,
171 HttpRequestMethod::POST,
172 HttpRequestMethod::PUT,
173 HttpRequestMethod::TRACE,
174 ]
175 .into_iter()
176 .collect(),
177 denied_methods: HashSet::new(),
178 allowed_hosts: HashSet::new(),
179 denied_hosts: HashSet::new(),
180 allowed_host_patterns: Box::new([]),
181 denied_host_patterns: Box::new([]),
182 allowed_port_ranges: vec![80..=80, 443..=443].into_boxed_slice(),
183 denied_port_ranges: Vec::new().into_boxed_slice(),
184 allowed_ip_ranges: Vec::new().into_boxed_slice(),
185 denied_ip_ranges: Vec::new().into_boxed_slice(),
186 static_dns_mapping: HashMap::new(),
187 trusted_static_dns_mapping: HashMap::new(),
188 allowed_headers: HashMap::new(),
189 denied_headers: HashMap::new(),
190 allowed_url_paths_router: Router::new(),
191 denied_url_paths_router: Router::new(),
192 validate_fn: None,
193 modify_request_fn: None,
194 modify_response_fn: None,
195 allow_non_global_ip_ranges: false,
196 method_acl_default: false,
197 host_acl_default: false,
198 port_acl_default: false,
199 ip_acl_default: false,
200 header_acl_default: true,
201 url_path_acl_default: true,
202 }
203 }
204}
205
206impl HttpAcl {
207 pub fn builder() -> HttpAclBuilder {
209 HttpAclBuilder::new()
210 }
211
212 pub fn is_scheme_allowed(&self, scheme: &str) -> AclClassification {
220 if scheme == "http" && self.allow_http || scheme == "https" && self.allow_https {
221 AclClassification::AllowedUserAcl
222 } else {
223 AclClassification::DeniedUserAcl
224 }
225 }
226
227 pub fn is_method_allowed(&self, method: impl Into<HttpRequestMethod>) -> AclClassification {
231 let method = method.into();
232 if self.allowed_methods.contains(&method) {
233 AclClassification::AllowedUserAcl
234 } else if self.denied_methods.contains(&method) {
235 AclClassification::DeniedUserAcl
236 } else if self.method_acl_default {
237 AclClassification::AllowedDefault
238 } else {
239 AclClassification::DeniedDefault
240 }
241 }
242
243 pub fn is_host_allowed(&self, host: &str) -> AclClassification {
250 if self.allowed_hosts.contains(host)
251 || self.allowed_host_patterns.iter().any(|p| p.matches(host))
252 {
253 AclClassification::AllowedUserAcl
254 } else if self.denied_hosts.contains(host)
255 || self.denied_host_patterns.iter().any(|p| p.matches(host))
256 {
257 AclClassification::DeniedUserAcl
258 } else if self.host_acl_default {
259 AclClassification::AllowedDefault
260 } else {
261 AclClassification::DeniedDefault
262 }
263 }
264
265 pub fn is_port_allowed(&self, port: u16) -> AclClassification {
267 if Self::is_port_in_ranges(port, &self.allowed_port_ranges) {
268 AclClassification::AllowedUserAcl
269 } else if Self::is_port_in_ranges(port, &self.denied_port_ranges) {
270 AclClassification::DeniedUserAcl
271 } else if self.port_acl_default {
272 AclClassification::AllowedDefault
273 } else {
274 AclClassification::DeniedDefault
275 }
276 }
277
278 pub fn is_ip_allowed(&self, ip: &IpAddr) -> AclClassification {
285 if !utils::ip::is_global_ip(ip) && !self.allow_non_global_ip_ranges {
286 AclClassification::DeniedNotGlobal
287 } else if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
288 AclClassification::AllowedUserAcl
289 } else if Self::is_ip_in_ranges(ip, &self.denied_ip_ranges) {
290 AclClassification::DeniedUserAcl
291 } else if self.ip_acl_default {
292 AclClassification::AllowedDefault
293 } else {
294 AclClassification::DeniedDefault
295 }
296 }
297
298 pub fn resolve_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
307 self.static_dns_mapping.get(host).copied()
308 }
309
310 pub fn resolve_trusted_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
319 self.trusted_static_dns_mapping.get(host).copied()
320 }
321
322 pub fn is_header_allowed(&self, header_name: &str, header_value: &str) -> AclClassification {
326 self.is_header_allowed_bytes(header_name, header_value.as_bytes())
327 }
328
329 pub fn is_header_allowed_bytes(
338 &self,
339 header_name: &str,
340 header_value: &[u8],
341 ) -> AclClassification {
342 if let Some(allowed_value) = self.allowed_headers.get(header_name) {
343 if allowed_value.as_deref().map(str::as_bytes) == Some(header_value)
344 || allowed_value.is_none()
345 {
346 AclClassification::AllowedUserAcl
347 } else {
348 AclClassification::DeniedUserAcl
349 }
350 } else if let Some(denied_value) = self.denied_headers.get(header_name) {
351 if denied_value.as_deref().map(str::as_bytes) == Some(header_value)
352 || denied_value.is_none()
353 {
354 AclClassification::DeniedUserAcl
355 } else {
356 AclClassification::AllowedUserAcl
357 }
358 } else if self.header_acl_default {
359 AclClassification::AllowedDefault
360 } else {
361 AclClassification::DeniedDefault
362 }
363 }
364
365 pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
369 if self.allowed_url_paths_router.at(url_path).is_ok() {
370 AclClassification::AllowedUserAcl
371 } else if self.denied_url_paths_router.at(url_path).is_ok() {
372 AclClassification::DeniedUserAcl
373 } else if self.url_path_acl_default {
374 AclClassification::AllowedDefault
375 } else {
376 AclClassification::DeniedDefault
377 }
378 }
379
380 pub fn is_valid<'h>(
386 &self,
387 scheme: &str,
388 authority: &Authority,
389 headers: impl Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h,
390 body: Option<&[u8]>,
391 ) -> AclClassification {
392 if let Some(validate_fn) = &self.validate_fn {
393 validate_fn(scheme, authority, Box::new(headers), body)
394 } else {
395 AclClassification::AllowedDefault
396 }
397 }
398
399 pub fn has_modify_request(&self) -> bool {
405 self.modify_request_fn.is_some()
406 }
407
408 pub fn has_modify_response(&self) -> bool {
412 self.modify_response_fn.is_some()
413 }
414
415 pub fn modify_request(
423 &self,
424 scheme: &str,
425 authority: &Authority,
426 mutation: &mut RequestMutation,
427 ) {
428 if let Some(modify_request_fn) = &self.modify_request_fn {
429 modify_request_fn(scheme, authority, mutation);
430 }
431 }
432
433 pub fn modify_response(
436 &self,
437 scheme: &str,
438 authority: &Authority,
439 mutation: &mut ResponseMutation,
440 ) {
441 if let Some(modify_response_fn) = &self.modify_response_fn {
442 modify_response_fn(scheme, authority, mutation);
443 }
444 }
445
446 fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
448 ranges.iter().any(|range| range.contains(ip))
449 }
450
451 fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
453 ranges.iter().any(|range| range.contains(&port))
454 }
455}
456
457#[non_exhaustive]
464#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
465pub enum AclClassification {
466 AllowedUserAcl,
468 AllowedDefault,
470 DeniedUserAcl,
472 DeniedDefault,
474 Denied(String),
479 DeniedNotGlobal,
481}
482
483impl std::fmt::Display for AclClassification {
484 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
485 match self {
486 AclClassification::AllowedUserAcl => {
487 write!(f, "The entity is allowed according to the allowed ACL.")
488 }
489 AclClassification::AllowedDefault => write!(
490 f,
491 "The entity is allowed because the default is to allow if no ACL match is found."
492 ),
493 AclClassification::DeniedUserAcl => {
494 write!(f, "The entity is denied according to the denied ACL.")
495 }
496 AclClassification::DeniedNotGlobal => {
497 write!(f, "The ip is denied because it is not global.")
498 }
499 AclClassification::DeniedDefault => write!(
500 f,
501 "The entity is denied because the default is to deny if no ACL match is found."
502 ),
503 AclClassification::Denied(reason) => {
504 write!(f, "The entity is denied because {reason}.")
505 }
506 }
507 }
508}
509
510impl AclClassification {
511 pub fn is_allowed(&self) -> bool {
513 matches!(
514 self,
515 AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
516 )
517 }
518
519 pub fn is_denied(&self) -> bool {
521 matches!(
522 self,
523 AclClassification::DeniedUserAcl
524 | AclClassification::Denied(_)
525 | AclClassification::DeniedDefault
526 | AclClassification::DeniedNotGlobal
527 )
528 }
529}
530
531#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
533#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
534pub enum HttpRequestMethod {
535 CONNECT,
537 DELETE,
539 GET,
541 HEAD,
543 OPTIONS,
545 PATCH,
547 POST,
549 PUT,
551 TRACE,
553 OTHER(Box<str>),
555}
556
557impl From<&str> for HttpRequestMethod {
558 fn from(method: &str) -> Self {
559 match method {
560 "CONNECT" => HttpRequestMethod::CONNECT,
561 "DELETE" => HttpRequestMethod::DELETE,
562 "GET" => HttpRequestMethod::GET,
563 "HEAD" => HttpRequestMethod::HEAD,
564 "OPTIONS" => HttpRequestMethod::OPTIONS,
565 "PATCH" => HttpRequestMethod::PATCH,
566 "POST" => HttpRequestMethod::POST,
567 "PUT" => HttpRequestMethod::PUT,
568 "TRACE" => HttpRequestMethod::TRACE,
569 _ => HttpRequestMethod::OTHER(method.into()),
570 }
571 }
572}
573
574impl HttpRequestMethod {
575 pub fn as_str(&self) -> &str {
577 match self {
578 HttpRequestMethod::CONNECT => "CONNECT",
579 HttpRequestMethod::DELETE => "DELETE",
580 HttpRequestMethod::GET => "GET",
581 HttpRequestMethod::HEAD => "HEAD",
582 HttpRequestMethod::OPTIONS => "OPTIONS",
583 HttpRequestMethod::PATCH => "PATCH",
584 HttpRequestMethod::POST => "POST",
585 HttpRequestMethod::PUT => "PUT",
586 HttpRequestMethod::TRACE => "TRACE",
587 HttpRequestMethod::OTHER(other) => other,
588 }
589 }
590}
591
592#[derive(Clone, Default)]
600pub struct HttpAclHooks {
601 pub validate_fn: Option<ValidateFn>,
603 pub modify_request_fn: Option<ModifyRequestFn>,
605 pub modify_response_fn: Option<ModifyResponseFn>,
607}
608
609#[derive(Default, Clone)]
624#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
625pub struct HttpAclBuilder {
626 allow_http: bool,
627 allow_https: bool,
628 allowed_methods: Vec<HttpRequestMethod>,
629 denied_methods: Vec<HttpRequestMethod>,
630 allowed_hosts: Vec<String>,
631 denied_hosts: Vec<String>,
632 #[cfg_attr(feature = "serde", serde(skip))]
633 allowed_host_patterns: Vec<HostPattern>,
634 #[cfg_attr(feature = "serde", serde(skip))]
635 denied_host_patterns: Vec<HostPattern>,
636 allowed_port_ranges: Vec<RangeInclusive<u16>>,
637 denied_port_ranges: Vec<RangeInclusive<u16>>,
638 allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
639 denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
640 static_dns_mapping: HashMap<String, SocketAddr>,
641 trusted_static_dns_mapping: HashMap<String, SocketAddr>,
642 allowed_headers: HashMap<String, Option<String>>,
643 denied_headers: HashMap<String, Option<String>>,
644 allowed_url_paths: Vec<String>,
645 #[cfg_attr(feature = "serde", serde(skip))]
646 allowed_url_paths_router: Router<()>,
647 denied_url_paths: Vec<String>,
648 #[cfg_attr(feature = "serde", serde(skip))]
649 denied_url_paths_router: Router<()>,
650 allow_non_global_ip_ranges: bool,
651 method_acl_default: bool,
652 host_acl_default: bool,
653 port_acl_default: bool,
654 ip_acl_default: bool,
655 header_acl_default: bool,
656 url_path_acl_default: bool,
657}
658
659impl std::fmt::Debug for HttpAclBuilder {
660 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
661 f.debug_struct("HttpAclBuilder")
662 .field("allow_http", &self.allow_http)
663 .field("allow_https", &self.allow_https)
664 .field("allowed_methods", &self.allowed_methods)
665 .field("denied_methods", &self.denied_methods)
666 .field("allowed_hosts", &self.allowed_hosts)
667 .field("denied_hosts", &self.denied_hosts)
668 .field("allowed_port_ranges", &self.allowed_port_ranges)
669 .field("denied_port_ranges", &self.denied_port_ranges)
670 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
671 .field("denied_ip_ranges", &self.denied_ip_ranges)
672 .field("static_dns_mapping", &self.static_dns_mapping)
673 .field(
674 "trusted_static_dns_mapping",
675 &self.trusted_static_dns_mapping,
676 )
677 .field("allowed_headers", &self.allowed_headers)
678 .field("denied_headers", &self.denied_headers)
679 .field("allowed_url_paths", &self.allowed_url_paths)
680 .field("denied_url_paths", &self.denied_url_paths)
681 .field(
682 "allow_non_global_ip_ranges",
683 &self.allow_non_global_ip_ranges,
684 )
685 .field("method_acl_default", &self.method_acl_default)
686 .field("host_acl_default", &self.host_acl_default)
687 .field("port_acl_default", &self.port_acl_default)
688 .field("ip_acl_default", &self.ip_acl_default)
689 .field("header_acl_default", &self.header_acl_default)
690 .field("url_path_acl_default", &self.url_path_acl_default)
691 .finish()
692 }
693}
694
695impl PartialEq for HttpAclBuilder {
696 fn eq(&self, other: &Self) -> bool {
697 self.allow_http == other.allow_http
698 && self.allow_https == other.allow_https
699 && self.allowed_methods == other.allowed_methods
700 && self.denied_methods == other.denied_methods
701 && self.allowed_hosts == other.allowed_hosts
702 && self.denied_hosts == other.denied_hosts
703 && self.allowed_port_ranges == other.allowed_port_ranges
704 && self.denied_port_ranges == other.denied_port_ranges
705 && self.allowed_ip_ranges == other.allowed_ip_ranges
706 && self.denied_ip_ranges == other.denied_ip_ranges
707 && self.static_dns_mapping == other.static_dns_mapping
708 && self.trusted_static_dns_mapping == other.trusted_static_dns_mapping
709 && self.allowed_headers == other.allowed_headers
710 && self.denied_headers == other.denied_headers
711 && self.allowed_url_paths == other.allowed_url_paths
712 && self.denied_url_paths == other.denied_url_paths
713 && self.allow_non_global_ip_ranges == other.allow_non_global_ip_ranges
714 && self.method_acl_default == other.method_acl_default
715 && self.host_acl_default == other.host_acl_default
716 && self.port_acl_default == other.port_acl_default
717 && self.ip_acl_default == other.ip_acl_default
718 && self.header_acl_default == other.header_acl_default
719 && self.url_path_acl_default == other.url_path_acl_default
720 }
721}
722
723impl HttpAclBuilder {
724 pub fn new() -> Self {
726 Self {
727 allow_http: true,
728 allow_https: true,
729 allowed_methods: vec![
730 HttpRequestMethod::CONNECT,
731 HttpRequestMethod::DELETE,
732 HttpRequestMethod::GET,
733 HttpRequestMethod::HEAD,
734 HttpRequestMethod::OPTIONS,
735 HttpRequestMethod::PATCH,
736 HttpRequestMethod::POST,
737 HttpRequestMethod::PUT,
738 HttpRequestMethod::TRACE,
739 ],
740 denied_methods: Vec::new(),
741 allowed_hosts: Vec::new(),
742 denied_hosts: Vec::new(),
743 allowed_host_patterns: Vec::new(),
744 denied_host_patterns: Vec::new(),
745 allowed_port_ranges: vec![80..=80, 443..=443],
746 denied_port_ranges: Vec::new(),
747 allowed_ip_ranges: Vec::new(),
748 denied_ip_ranges: Vec::new(),
749 allowed_headers: HashMap::new(),
750 denied_headers: HashMap::new(),
751 allowed_url_paths: Vec::new(),
752 allowed_url_paths_router: Router::new(),
753 denied_url_paths: Vec::new(),
754 denied_url_paths_router: Router::new(),
755 allow_non_global_ip_ranges: false,
756 static_dns_mapping: HashMap::new(),
757 trusted_static_dns_mapping: HashMap::new(),
758 method_acl_default: false,
759 host_acl_default: false,
760 port_acl_default: false,
761 ip_acl_default: false,
762 header_acl_default: true,
763 url_path_acl_default: true,
764 }
765 }
766
767 pub fn http(mut self, allow: bool) -> Self {
769 self.allow_http = allow;
770 self
771 }
772
773 pub fn https(mut self, allow: bool) -> Self {
775 self.allow_https = allow;
776 self
777 }
778
779 pub fn non_global_ip_ranges(mut self, allow: bool) -> Self {
783 self.allow_non_global_ip_ranges = allow;
784 self
785 }
786
787 pub fn method_acl_default(mut self, allow: bool) -> Self {
789 self.method_acl_default = allow;
790 self
791 }
792
793 pub fn host_acl_default(mut self, allow: bool) -> Self {
795 self.host_acl_default = allow;
796 self
797 }
798
799 pub fn port_acl_default(mut self, allow: bool) -> Self {
801 self.port_acl_default = allow;
802 self
803 }
804
805 pub fn ip_acl_default(mut self, allow: bool) -> Self {
807 self.ip_acl_default = allow;
808 self
809 }
810
811 pub fn header_acl_default(mut self, allow: bool) -> Self {
813 self.header_acl_default = allow;
814 self
815 }
816
817 pub fn url_path_acl_default(mut self, allow: bool) -> Self {
819 self.url_path_acl_default = allow;
820 self
821 }
822
823 pub fn add_allowed_method(
827 mut self,
828 method: impl Into<HttpRequestMethod>,
829 ) -> Result<Self, AddError> {
830 let method = method.into();
831 if self.denied_methods.contains(&method) {
832 Err(AddError::AlreadyDeniedMethod(method))
833 } else if self.allowed_methods.contains(&method) {
834 Err(AddError::AlreadyAllowedMethod(method))
835 } else {
836 self.allowed_methods.push(method);
837 Ok(self)
838 }
839 }
840
841 pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
845 let method = method.into();
846 self.allowed_methods.retain(|m| m != &method);
847 self
848 }
849
850 pub fn allowed_methods(
854 mut self,
855 methods: Vec<impl Into<HttpRequestMethod>>,
856 ) -> Result<Self, AddError> {
857 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
858
859 for method in &methods {
860 if self.denied_methods.contains(method) {
861 return Err(AddError::AlreadyDeniedMethod(method.clone()));
862 }
863 }
864 self.allowed_methods = methods;
865 Ok(self)
866 }
867
868 pub fn clear_allowed_methods(mut self) -> Self {
870 self.allowed_methods.clear();
871 self
872 }
873
874 pub fn add_denied_method(
878 mut self,
879 method: impl Into<HttpRequestMethod>,
880 ) -> Result<Self, AddError> {
881 let method = method.into();
882 if self.allowed_methods.contains(&method) {
883 Err(AddError::AlreadyAllowedMethod(method))
884 } else if self.denied_methods.contains(&method) {
885 Err(AddError::AlreadyDeniedMethod(method))
886 } else {
887 self.denied_methods.push(method);
888 Ok(self)
889 }
890 }
891
892 pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
896 let method = method.into();
897 self.denied_methods.retain(|m| m != &method);
898 self
899 }
900
901 pub fn denied_methods(
905 mut self,
906 methods: Vec<impl Into<HttpRequestMethod>>,
907 ) -> Result<Self, AddError> {
908 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
909
910 for method in &methods {
911 if self.allowed_methods.contains(method) {
912 return Err(AddError::AlreadyAllowedMethod(method.clone()));
913 }
914 }
915 self.denied_methods = methods;
916 Ok(self)
917 }
918
919 pub fn clear_denied_methods(mut self) -> Self {
921 self.denied_methods.clear();
922 self
923 }
924
925 pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
939 let pattern = Self::validate_host_or_pattern(&host)?;
940
941 if self.denied_hosts.contains(&host) {
942 return Err(AddError::AlreadyDeniedHost(host));
943 }
944 if self.allowed_hosts.contains(&host) {
945 return Err(AddError::AlreadyAllowedHost(host));
946 }
947
948 if let Some(pattern) = pattern {
949 self.allowed_host_patterns.push(pattern);
950 }
951 self.allowed_hosts.push(host);
952 Ok(self)
953 }
954
955 pub fn remove_allowed_host(mut self, host: String) -> Self {
959 self.allowed_hosts.retain(|h| h != &host);
960 self.allowed_host_patterns = Self::compile_host_patterns(&self.allowed_hosts);
961 self
962 }
963
964 pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
970 let mut patterns = Vec::new();
971 for host in &hosts {
972 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
973 patterns.push(pattern);
974 }
975 if self.denied_hosts.contains(host) {
976 return Err(AddError::AlreadyDeniedHost(host.clone()));
977 }
978 }
979 self.allowed_host_patterns = patterns;
980 self.allowed_hosts = hosts;
981 Ok(self)
982 }
983
984 pub fn clear_allowed_hosts(mut self) -> Self {
986 self.allowed_hosts.clear();
987 self.allowed_host_patterns.clear();
988 self
989 }
990
991 pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
997 let pattern = Self::validate_host_or_pattern(&host)?;
998
999 if self.allowed_hosts.contains(&host) {
1000 return Err(AddError::AlreadyAllowedHost(host));
1001 }
1002 if self.denied_hosts.contains(&host) {
1003 return Err(AddError::AlreadyDeniedHost(host));
1004 }
1005
1006 if let Some(pattern) = pattern {
1007 self.denied_host_patterns.push(pattern);
1008 }
1009 self.denied_hosts.push(host);
1010 Ok(self)
1011 }
1012
1013 pub fn remove_denied_host(mut self, host: String) -> Self {
1017 self.denied_hosts.retain(|h| h != &host);
1018 self.denied_host_patterns = Self::compile_host_patterns(&self.denied_hosts);
1019 self
1020 }
1021
1022 pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
1028 let mut patterns = Vec::new();
1029 for host in &hosts {
1030 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
1031 patterns.push(pattern);
1032 }
1033 if self.allowed_hosts.contains(host) {
1034 return Err(AddError::AlreadyAllowedHost(host.clone()));
1035 }
1036 }
1037 self.denied_host_patterns = patterns;
1038 self.denied_hosts = hosts;
1039 Ok(self)
1040 }
1041
1042 pub fn clear_denied_hosts(mut self) -> Self {
1044 self.denied_hosts.clear();
1045 self.denied_host_patterns.clear();
1046 self
1047 }
1048
1049 fn validate_host_or_pattern(host: &str) -> Result<Option<HostPattern>, AddError> {
1052 if is_wildcard_host(host) {
1053 match HostPattern::parse(host) {
1054 Some(pattern) => Ok(Some(pattern)),
1055 None => Err(AddError::InvalidEntity(host.to_string())),
1056 }
1057 } else if utils::authority::is_valid_host(host) {
1058 Ok(None)
1059 } else {
1060 Err(AddError::InvalidEntity(host.to_string()))
1061 }
1062 }
1063
1064 fn compile_host_patterns(hosts: &[String]) -> Vec<HostPattern> {
1066 hosts
1067 .iter()
1068 .filter(|h| is_wildcard_host(h))
1069 .filter_map(|h| HostPattern::parse(h))
1070 .collect()
1071 }
1072
1073 pub fn add_allowed_port_range(
1075 mut self,
1076 port_range: RangeInclusive<u16>,
1077 ) -> Result<Self, AddError> {
1078 if self.denied_port_ranges.contains(&port_range) {
1079 Err(AddError::AlreadyDeniedPortRange(port_range))
1080 } else if self.allowed_port_ranges.contains(&port_range) {
1081 Err(AddError::AlreadyAllowedPortRange(port_range))
1082 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
1083 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
1084 {
1085 Err(AddError::Overlaps(format!("{port_range:?}")))
1086 } else {
1087 self.allowed_port_ranges.push(port_range);
1088 Ok(self)
1089 }
1090 }
1091
1092 pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1094 self.allowed_port_ranges.retain(|p| p != &port_range);
1095 self
1096 }
1097
1098 pub fn allowed_port_ranges(
1100 mut self,
1101 port_ranges: Vec<RangeInclusive<u16>>,
1102 ) -> Result<Self, AddError> {
1103 for (i, port_range) in port_ranges.iter().enumerate() {
1104 if self.denied_port_ranges.contains(port_range) {
1105 return Err(AddError::AlreadyDeniedPortRange(port_range.clone()));
1106 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1107 || utils::range_overlaps(&self.denied_port_ranges, port_range, None)
1108 {
1109 return Err(AddError::Overlaps(format!("{port_range:?}")));
1110 }
1111 }
1112 self.allowed_port_ranges = port_ranges;
1113 Ok(self)
1114 }
1115
1116 pub fn clear_allowed_port_ranges(mut self) -> Self {
1118 self.allowed_port_ranges.clear();
1119 self
1120 }
1121
1122 pub fn add_denied_port_range(
1124 mut self,
1125 port_range: RangeInclusive<u16>,
1126 ) -> Result<Self, AddError> {
1127 if self.allowed_port_ranges.contains(&port_range) {
1128 Err(AddError::AlreadyAllowedPortRange(port_range))
1129 } else if self.denied_port_ranges.contains(&port_range) {
1130 Err(AddError::AlreadyDeniedPortRange(port_range))
1131 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
1132 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
1133 {
1134 Err(AddError::Overlaps(format!("{port_range:?}")))
1135 } else {
1136 self.denied_port_ranges.push(port_range);
1137 Ok(self)
1138 }
1139 }
1140
1141 pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1143 self.denied_port_ranges.retain(|p| p != &port_range);
1144 self
1145 }
1146
1147 pub fn denied_port_ranges(
1149 mut self,
1150 port_ranges: Vec<RangeInclusive<u16>>,
1151 ) -> Result<Self, AddError> {
1152 for (i, port_range) in port_ranges.iter().enumerate() {
1153 if self.allowed_port_ranges.contains(port_range) {
1154 return Err(AddError::AlreadyAllowedPortRange(port_range.clone()));
1155 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1156 || utils::range_overlaps(&self.allowed_port_ranges, port_range, None)
1157 {
1158 return Err(AddError::Overlaps(format!("{port_range:?}")));
1159 }
1160 }
1161 self.denied_port_ranges = port_ranges;
1162 Ok(self)
1163 }
1164
1165 pub fn clear_denied_port_ranges(mut self) -> Self {
1167 self.denied_port_ranges.clear();
1168 self
1169 }
1170
1171 pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1173 let ip_range = ip_range
1174 .into_range()
1175 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1176 if self.denied_ip_ranges.contains(&ip_range) {
1177 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1178 } else if self.allowed_ip_ranges.contains(&ip_range) {
1179 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1180 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1181 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1182 {
1183 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1184 }
1185 self.allowed_ip_ranges.push(ip_range);
1186 Ok(self)
1187 }
1188
1189 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
1191 mut self,
1192 ip_range: Ip,
1193 ) -> Result<Self, AddError> {
1194 let ip_range = ip_range
1195 .into_range()
1196 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1197 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
1198 Ok(self)
1199 }
1200
1201 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
1203 mut self,
1204 ip_ranges: Vec<Ip>,
1205 ) -> Result<Self, AddError> {
1206 let ip_ranges = ip_ranges
1207 .into_iter()
1208 .map(|ip| ip.into_range())
1209 .collect::<Option<Vec<_>>>()
1210 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1211 for (i, ip_range) in ip_ranges.iter().enumerate() {
1212 if self.denied_ip_ranges.contains(ip_range) {
1213 return Err(AddError::AlreadyDeniedIpRange(ip_range.clone()));
1214 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1215 || utils::range_overlaps(&self.denied_ip_ranges, ip_range, None)
1216 {
1217 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1218 }
1219 }
1220 self.allowed_ip_ranges = ip_ranges;
1221 Ok(self)
1222 }
1223
1224 pub fn clear_allowed_ip_ranges(mut self) -> Self {
1226 self.allowed_ip_ranges.clear();
1227 self
1228 }
1229
1230 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1232 let ip_range = ip_range
1233 .into_range()
1234 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1235 if self.allowed_ip_ranges.contains(&ip_range) {
1236 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1237 } else if self.denied_ip_ranges.contains(&ip_range) {
1238 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1239 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1240 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1241 {
1242 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1243 }
1244 self.denied_ip_ranges.push(ip_range);
1245 Ok(self)
1246 }
1247
1248 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
1250 mut self,
1251 ip_range: Ip,
1252 ) -> Result<Self, AddError> {
1253 let ip_range = ip_range
1254 .into_range()
1255 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1256 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
1257 Ok(self)
1258 }
1259
1260 pub fn denied_ip_ranges<Ip: IntoIpRange>(
1262 mut self,
1263 ip_ranges: Vec<Ip>,
1264 ) -> Result<Self, AddError> {
1265 let ip_ranges = ip_ranges
1266 .into_iter()
1267 .map(|ip| ip.into_range())
1268 .collect::<Option<Vec<_>>>()
1269 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1270 for (i, ip_range) in ip_ranges.iter().enumerate() {
1271 if self.allowed_ip_ranges.contains(ip_range) {
1272 return Err(AddError::AlreadyAllowedIpRange(ip_range.clone()));
1273 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1274 || utils::range_overlaps(&self.allowed_ip_ranges, ip_range, None)
1275 {
1276 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1277 }
1278 }
1279 self.denied_ip_ranges = ip_ranges;
1280 Ok(self)
1281 }
1282
1283 pub fn clear_denied_ip_ranges(mut self) -> Self {
1285 self.denied_ip_ranges.clear();
1286 self
1287 }
1288
1289 pub fn add_static_dns_mapping(
1297 mut self,
1298 host: String,
1299 sock_addr: SocketAddr,
1300 ) -> Result<Self, AddError> {
1301 if !utils::authority::is_valid_host(&host) {
1302 return Err(AddError::InvalidEntity(host));
1303 }
1304 if self.trusted_static_dns_mapping.contains_key(&host) {
1305 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1306 host, sock_addr,
1307 ));
1308 }
1309 if let Entry::Vacant(e) = self.static_dns_mapping.entry(host.clone()) {
1310 e.insert(sock_addr);
1311 Ok(self)
1312 } else {
1313 Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr))
1314 }
1315 }
1316
1317 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
1321 self.static_dns_mapping.remove(host);
1322 self
1323 }
1324
1325 pub fn static_dns_mappings(
1329 mut self,
1330 mappings: HashMap<String, SocketAddr>,
1331 ) -> Result<Self, AddError> {
1332 for (host, ip) in &mappings {
1333 if !utils::authority::is_valid_host(host) {
1334 return Err(AddError::InvalidEntity(host.clone()));
1335 }
1336 if self.trusted_static_dns_mapping.contains_key(host) {
1337 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1338 host.clone(),
1339 *ip,
1340 ));
1341 }
1342 if self.static_dns_mapping.contains_key(host) {
1343 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1344 }
1345 self.static_dns_mapping.insert(host.to_string(), *ip);
1346 }
1347 Ok(self)
1348 }
1349
1350 pub fn clear_static_dns_mappings(mut self) -> Self {
1352 self.static_dns_mapping.clear();
1353 self
1354 }
1355
1356 pub fn add_trusted_static_dns_mapping(
1365 mut self,
1366 host: String,
1367 sock_addr: SocketAddr,
1368 ) -> Result<Self, AddError> {
1369 if !utils::authority::is_valid_host(&host) {
1370 return Err(AddError::InvalidEntity(host));
1371 }
1372 if self.static_dns_mapping.contains_key(&host) {
1373 return Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr));
1374 }
1375 if let Entry::Vacant(e) = self.trusted_static_dns_mapping.entry(host.clone()) {
1376 e.insert(sock_addr);
1377 Ok(self)
1378 } else {
1379 Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1380 host, sock_addr,
1381 ))
1382 }
1383 }
1384
1385 pub fn remove_trusted_static_dns_mapping(mut self, host: &str) -> Self {
1389 self.trusted_static_dns_mapping.remove(host);
1390 self
1391 }
1392
1393 pub fn trusted_static_dns_mappings(
1397 mut self,
1398 mappings: HashMap<String, SocketAddr>,
1399 ) -> Result<Self, AddError> {
1400 for (host, ip) in &mappings {
1401 if !utils::authority::is_valid_host(host) {
1402 return Err(AddError::InvalidEntity(host.clone()));
1403 }
1404 if self.static_dns_mapping.contains_key(host) {
1405 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1406 }
1407 if self.trusted_static_dns_mapping.contains_key(host) {
1408 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1409 host.clone(),
1410 *ip,
1411 ));
1412 }
1413 self.trusted_static_dns_mapping
1414 .insert(host.to_string(), *ip);
1415 }
1416 Ok(self)
1417 }
1418
1419 pub fn clear_trusted_static_dns_mappings(mut self) -> Self {
1421 self.trusted_static_dns_mapping.clear();
1422 self
1423 }
1424
1425 pub fn add_allowed_header(
1431 mut self,
1432 header: String,
1433 value: Option<String>,
1434 ) -> Result<Self, AddError> {
1435 if self.denied_headers.contains_key(&header) {
1436 Err(AddError::AlreadyDeniedHeader(header, value.clone()))
1437 } else if let Entry::Vacant(e) = self.allowed_headers.entry(header.clone()) {
1438 e.insert(value);
1439 Ok(self)
1440 } else {
1441 Err(AddError::AlreadyAllowedHeader(header, value))
1442 }
1443 }
1444
1445 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1449 self.allowed_headers.remove(header);
1450 self
1451 }
1452
1453 pub fn allowed_headers(
1457 mut self,
1458 headers: HashMap<String, Option<String>>,
1459 ) -> Result<Self, AddError> {
1460 for (header, value) in &headers {
1461 if self.denied_headers.contains_key(header) {
1462 return Err(AddError::AlreadyDeniedHeader(header.clone(), value.clone()));
1463 }
1464 }
1465 self.allowed_headers = headers;
1466 Ok(self)
1467 }
1468
1469 pub fn clear_allowed_headers(mut self) -> Self {
1471 self.allowed_headers.clear();
1472 self
1473 }
1474
1475 pub fn add_denied_header(
1481 mut self,
1482 header: String,
1483 value: Option<String>,
1484 ) -> Result<Self, AddError> {
1485 if self.allowed_headers.contains_key(&header) {
1486 Err(AddError::AlreadyAllowedHeader(header, value.clone()))
1487 } else if let Entry::Vacant(e) = self.denied_headers.entry(header.clone()) {
1488 e.insert(value);
1489 Ok(self)
1490 } else {
1491 Err(AddError::AlreadyDeniedHeader(header, value))
1492 }
1493 }
1494
1495 pub fn remove_denied_header(mut self, header: &str) -> Self {
1499 self.denied_headers.remove(header);
1500 self
1501 }
1502
1503 pub fn denied_headers(
1507 mut self,
1508 headers: HashMap<String, Option<String>>,
1509 ) -> Result<Self, AddError> {
1510 for (header, value) in &headers {
1511 if self.allowed_headers.contains_key(header) {
1512 return Err(AddError::AlreadyAllowedHeader(
1513 header.clone(),
1514 value.clone(),
1515 ));
1516 }
1517 }
1518 self.denied_headers = headers;
1519 Ok(self)
1520 }
1521
1522 pub fn clear_denied_headers(mut self) -> Self {
1524 self.denied_headers.clear();
1525 self
1526 }
1527
1528 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1532 if self.denied_url_paths.contains(&url_path)
1533 || self.denied_url_paths_router.at(&url_path).is_ok()
1534 {
1535 Err(AddError::AlreadyDeniedUrlPath(url_path))
1536 } else if self.allowed_url_paths.contains(&url_path)
1537 || self.allowed_url_paths_router.at(&url_path).is_ok()
1538 {
1539 Err(AddError::AlreadyAllowedUrlPath(url_path))
1540 } else {
1541 self.allowed_url_paths.push(url_path.clone());
1542 self.allowed_url_paths_router
1543 .insert(url_path, ())
1544 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1545 Ok(self)
1546 }
1547 }
1548
1549 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1553 self.allowed_url_paths.retain(|p| p != url_path);
1554 self.allowed_url_paths_router = {
1555 let mut router = Router::new();
1556 for url_path in &self.allowed_url_paths {
1557 router
1558 .insert(url_path.clone(), ())
1559 .expect("failed to insert url path");
1560 }
1561 router
1562 };
1563 self
1564 }
1565
1566 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1570 for url_path in &url_paths {
1571 if self.denied_url_paths.contains(url_path)
1572 || self.denied_url_paths_router.at(url_path).is_ok()
1573 {
1574 return Err(AddError::AlreadyDeniedUrlPath(url_path.clone()));
1575 }
1576 }
1577 self.allowed_url_paths_router = Router::new();
1578 for url_path in &url_paths {
1579 self.allowed_url_paths_router
1580 .insert(url_path.clone(), ())
1581 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1582 }
1583 self.allowed_url_paths = url_paths;
1584 Ok(self)
1585 }
1586
1587 pub fn clear_allowed_url_paths(mut self) -> Self {
1589 self.allowed_url_paths.clear();
1590 self.allowed_url_paths_router = Router::new();
1591 self
1592 }
1593
1594 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1598 if self.allowed_url_paths.contains(&url_path)
1599 || self.allowed_url_paths_router.at(&url_path).is_ok()
1600 {
1601 Err(AddError::AlreadyAllowedUrlPath(url_path))
1602 } else if self.denied_url_paths.contains(&url_path)
1603 || self.denied_url_paths_router.at(&url_path).is_ok()
1604 {
1605 Err(AddError::AlreadyDeniedUrlPath(url_path))
1606 } else {
1607 self.denied_url_paths.push(url_path.clone());
1608 self.denied_url_paths_router
1609 .insert(url_path, ())
1610 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1611 Ok(self)
1612 }
1613 }
1614
1615 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1619 self.denied_url_paths.retain(|p| p != url_path);
1620 self.denied_url_paths_router = {
1621 let mut router = Router::new();
1622 for url_path in &self.denied_url_paths {
1623 router
1624 .insert(url_path.clone(), ())
1625 .expect("failed to insert url path");
1626 }
1627 router
1628 };
1629 self
1630 }
1631
1632 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1636 for url_path in &url_paths {
1637 if self.allowed_url_paths.contains(url_path)
1638 || self.allowed_url_paths_router.at(url_path).is_ok()
1639 {
1640 return Err(AddError::AlreadyAllowedUrlPath(url_path.clone()));
1641 }
1642 }
1643 self.denied_url_paths_router = Router::new();
1644 for url_path in &url_paths {
1645 self.denied_url_paths_router
1646 .insert(url_path.clone(), ())
1647 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1648 }
1649 self.denied_url_paths = url_paths;
1650 Ok(self)
1651 }
1652
1653 pub fn clear_denied_url_paths(mut self) -> Self {
1655 self.denied_url_paths.clear();
1656 self.denied_url_paths_router = Router::new();
1657 self
1658 }
1659
1660 pub fn build(self) -> HttpAcl {
1667 self.build_full(HttpAclHooks::default())
1668 }
1669
1670 pub fn build_full(self, hooks: HttpAclHooks) -> HttpAcl {
1677 HttpAcl {
1678 allow_http: self.allow_http,
1679 allow_https: self.allow_https,
1680 allowed_methods: self.allowed_methods.into_iter().collect(),
1681 denied_methods: self.denied_methods.into_iter().collect(),
1682 allowed_hosts: self
1683 .allowed_hosts
1684 .into_iter()
1685 .filter(|h| !is_wildcard_host(h))
1686 .map(|x| x.into_boxed_str())
1687 .collect(),
1688 denied_hosts: self
1689 .denied_hosts
1690 .into_iter()
1691 .filter(|h| !is_wildcard_host(h))
1692 .map(|x| x.into_boxed_str())
1693 .collect(),
1694 allowed_host_patterns: self.allowed_host_patterns.into_boxed_slice(),
1695 denied_host_patterns: self.denied_host_patterns.into_boxed_slice(),
1696 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1697 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1698 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1699 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1700 allowed_headers: self
1701 .allowed_headers
1702 .into_iter()
1703 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1704 .collect(),
1705 denied_headers: self
1706 .denied_headers
1707 .into_iter()
1708 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1709 .collect(),
1710 allowed_url_paths_router: self.allowed_url_paths_router,
1711 denied_url_paths_router: self.denied_url_paths_router,
1712 static_dns_mapping: self
1713 .static_dns_mapping
1714 .into_iter()
1715 .map(|(k, v)| (k.into_boxed_str(), v))
1716 .collect(),
1717 trusted_static_dns_mapping: self
1718 .trusted_static_dns_mapping
1719 .into_iter()
1720 .map(|(k, v)| (k.into_boxed_str(), v))
1721 .collect(),
1722 validate_fn: hooks.validate_fn,
1723 modify_request_fn: hooks.modify_request_fn,
1724 modify_response_fn: hooks.modify_response_fn,
1725 allow_non_global_ip_ranges: self.allow_non_global_ip_ranges,
1726 method_acl_default: self.method_acl_default,
1727 host_acl_default: self.host_acl_default,
1728 port_acl_default: self.port_acl_default,
1729 ip_acl_default: self.ip_acl_default,
1730 header_acl_default: self.header_acl_default,
1731 url_path_acl_default: self.url_path_acl_default,
1732 }
1733 }
1734
1735 pub fn try_build_full(mut self, hooks: HttpAclHooks) -> Result<HttpAcl, AddError> {
1752 if !utils::has_unique_elements(&self.allowed_methods) {
1753 return Err(AddError::NotUnique(
1754 "Allowed methods must be unique.".to_string(),
1755 ));
1756 }
1757 for method in &self.allowed_methods {
1758 if self.denied_methods.contains(method) {
1759 return Err(AddError::BothAllowedAndDenied(format!(
1760 "Method `{}`",
1761 method.as_str()
1762 )));
1763 }
1764 }
1765 if !utils::has_unique_elements(&self.denied_methods) {
1766 return Err(AddError::NotUnique(
1767 "Denied methods must be unique.".to_string(),
1768 ));
1769 }
1770 for method in &self.denied_methods {
1771 if self.allowed_methods.contains(method) {
1772 return Err(AddError::BothAllowedAndDenied(format!(
1773 "Method `{}`",
1774 method.as_str()
1775 )));
1776 }
1777 }
1778 if !utils::has_unique_elements(&self.allowed_hosts) {
1779 return Err(AddError::NotUnique(
1780 "Allowed hosts must be unique.".to_string(),
1781 ));
1782 }
1783 for host in &self.allowed_hosts {
1784 if is_wildcard_host(host) {
1785 match HostPattern::parse(host) {
1786 Some(pattern) => {
1787 if !self.allowed_host_patterns.contains(&pattern) {
1788 self.allowed_host_patterns.push(pattern);
1789 }
1790 }
1791 None => return Err(AddError::InvalidEntity(host.to_string())),
1792 }
1793 } else if !utils::authority::is_valid_host(host) {
1794 return Err(AddError::InvalidEntity(host.to_string()));
1795 }
1796 if self.denied_hosts.contains(host) {
1797 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1798 }
1799 }
1800 if !utils::has_unique_elements(&self.denied_hosts) {
1801 return Err(AddError::NotUnique(
1802 "Denied hosts must be unique.".to_string(),
1803 ));
1804 }
1805 for host in &self.denied_hosts {
1806 if is_wildcard_host(host) {
1807 match HostPattern::parse(host) {
1808 Some(pattern) => {
1809 if !self.denied_host_patterns.contains(&pattern) {
1810 self.denied_host_patterns.push(pattern);
1811 }
1812 }
1813 None => return Err(AddError::InvalidEntity(host.to_string())),
1814 }
1815 } else if !utils::authority::is_valid_host(host) {
1816 return Err(AddError::InvalidEntity(host.to_string()));
1817 }
1818 if self.allowed_hosts.contains(host) {
1819 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1820 }
1821 }
1822 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1823 return Err(AddError::NotUnique(
1824 "Allowed port ranges must be unique.".to_string(),
1825 ));
1826 }
1827 if utils::has_overlapping_ranges(&self.allowed_port_ranges) {
1828 return Err(AddError::Overlaps(
1829 "Allowed port ranges must not overlap.".to_string(),
1830 ));
1831 }
1832 for port_range in &self.allowed_port_ranges {
1833 if self.denied_port_ranges.contains(port_range) {
1834 return Err(AddError::BothAllowedAndDenied(format!(
1835 "Port range `{port_range:?}`"
1836 )));
1837 }
1838 }
1839 if !utils::has_unique_elements(&self.denied_port_ranges) {
1840 return Err(AddError::NotUnique(
1841 "Denied port ranges must be unique.".to_string(),
1842 ));
1843 }
1844 if utils::has_overlapping_ranges(&self.denied_port_ranges) {
1845 return Err(AddError::Overlaps(
1846 "Denied port ranges must not overlap.".to_string(),
1847 ));
1848 }
1849 for port_range in &self.denied_port_ranges {
1850 if self.allowed_port_ranges.contains(port_range) {
1851 return Err(AddError::BothAllowedAndDenied(format!(
1852 "Port range `{port_range:?}`"
1853 )));
1854 }
1855 }
1856 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1857 return Err(AddError::NotUnique(
1858 "Allowed IP ranges must be unique.".to_string(),
1859 ));
1860 }
1861 if utils::has_overlapping_ranges(&self.allowed_ip_ranges) {
1862 return Err(AddError::Overlaps(
1863 "Allowed IP ranges must not overlap.".to_string(),
1864 ));
1865 }
1866 for ip_range in &self.allowed_ip_ranges {
1867 if self.denied_ip_ranges.contains(ip_range) {
1868 return Err(AddError::BothAllowedAndDenied(format!(
1869 "IP range `{ip_range:?}`"
1870 )));
1871 }
1872
1873 if (!utils::ip::is_global_ip(ip_range.start())
1874 || !utils::ip::is_global_ip(ip_range.end()))
1875 && !self.allow_non_global_ip_ranges
1876 {
1877 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1878 }
1879 }
1880 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1881 return Err(AddError::NotUnique(
1882 "Denied IP ranges must be unique.".to_string(),
1883 ));
1884 }
1885 if utils::has_overlapping_ranges(&self.denied_ip_ranges) {
1886 return Err(AddError::Overlaps(
1887 "Denied IP ranges must not overlap.".to_string(),
1888 ));
1889 }
1890 for ip_range in &self.denied_ip_ranges {
1891 if self.allowed_ip_ranges.contains(ip_range) {
1892 return Err(AddError::BothAllowedAndDenied(format!(
1893 "IP range `{ip_range:?}`"
1894 )));
1895 }
1896
1897 if (!utils::ip::is_global_ip(ip_range.start())
1898 || !utils::ip::is_global_ip(ip_range.end()))
1899 && !self.allow_non_global_ip_ranges
1900 {
1901 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1902 }
1903 }
1904 if !utils::has_unique_elements(&self.static_dns_mapping) {
1905 return Err(AddError::NotUnique(
1906 "Static DNS mapping must be unique.".to_string(),
1907 ));
1908 }
1909 for (host, addr) in &self.static_dns_mapping {
1910 if !utils::authority::is_valid_host(host) {
1911 return Err(AddError::InvalidEntity(host.to_string()));
1912 }
1913 if self.trusted_static_dns_mapping.contains_key(host) {
1914 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1915 host.to_string(),
1916 *addr,
1917 ));
1918 }
1919 }
1920 if !utils::has_unique_elements(&self.trusted_static_dns_mapping) {
1921 return Err(AddError::NotUnique(
1922 "Trusted static DNS mapping must be unique.".to_string(),
1923 ));
1924 }
1925 for host in self.trusted_static_dns_mapping.keys() {
1926 if !utils::authority::is_valid_host(host) {
1927 return Err(AddError::InvalidEntity(host.to_string()));
1928 }
1929 }
1930 if !utils::has_unique_elements(&self.allowed_url_paths) {
1931 return Err(AddError::NotUnique(
1932 "Allowed URL paths must be unique.".to_string(),
1933 ));
1934 }
1935 for url_path in &self.allowed_url_paths {
1936 if self.denied_url_paths.contains(url_path)
1937 || self.denied_url_paths_router.at(url_path).is_ok()
1938 {
1939 return Err(AddError::BothAllowedAndDenied(format!(
1940 "URL path `{url_path}`"
1941 )));
1942 } else if self.allowed_url_paths_router.at(url_path).is_err() {
1943 self.allowed_url_paths_router
1944 .insert(url_path.clone(), ())
1945 .map_err(|_| {
1946 AddError::InvalidEntity(format!(
1947 "Failed to insert allowed URL path `{url_path}`."
1948 ))
1949 })?;
1950 }
1951 }
1952 if !utils::has_unique_elements(&self.denied_url_paths) {
1953 return Err(AddError::NotUnique(
1954 "Denied URL paths must be unique.".to_string(),
1955 ));
1956 }
1957 for url_path in &self.denied_url_paths {
1958 if self.allowed_url_paths.contains(url_path)
1959 || self.allowed_url_paths_router.at(url_path).is_ok()
1960 {
1961 return Err(AddError::BothAllowedAndDenied(format!(
1962 "URL path `{url_path}`"
1963 )));
1964 } else if self.denied_url_paths_router.at(url_path).is_err() {
1965 self.denied_url_paths_router
1966 .insert(url_path.clone(), ())
1967 .map_err(|_| {
1968 AddError::InvalidEntity(format!(
1969 "Failed to insert denied URL path `{url_path}`."
1970 ))
1971 })?;
1972 }
1973 }
1974 Ok(self.build_full(hooks))
1975 }
1976
1977 pub fn try_build(self) -> Result<HttpAcl, AddError> {
1981 self.try_build_full(HttpAclHooks::default())
1982 }
1983}