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 if let Some(allowed_value) = self.allowed_headers.get(header_name) {
327 if allowed_value.as_deref() == Some(header_value) || allowed_value.is_none() {
328 AclClassification::AllowedUserAcl
329 } else {
330 AclClassification::DeniedUserAcl
331 }
332 } else if let Some(denied_value) = self.denied_headers.get(header_name) {
333 if denied_value.as_deref() == Some(header_value) || denied_value.is_none() {
334 AclClassification::DeniedUserAcl
335 } else {
336 AclClassification::AllowedUserAcl
337 }
338 } else if self.header_acl_default {
339 AclClassification::AllowedDefault
340 } else {
341 AclClassification::DeniedDefault
342 }
343 }
344
345 pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
349 if self.allowed_url_paths_router.at(url_path).is_ok() {
350 AclClassification::AllowedUserAcl
351 } else if self.denied_url_paths_router.at(url_path).is_ok() {
352 AclClassification::DeniedUserAcl
353 } else if self.url_path_acl_default {
354 AclClassification::AllowedDefault
355 } else {
356 AclClassification::DeniedDefault
357 }
358 }
359
360 pub fn is_valid<'h>(
366 &self,
367 scheme: &str,
368 authority: &Authority,
369 headers: impl Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h,
370 body: Option<&[u8]>,
371 ) -> AclClassification {
372 if let Some(validate_fn) = &self.validate_fn {
373 validate_fn(scheme, authority, Box::new(headers), body)
374 } else {
375 AclClassification::AllowedDefault
376 }
377 }
378
379 pub fn has_modify_request(&self) -> bool {
385 self.modify_request_fn.is_some()
386 }
387
388 pub fn has_modify_response(&self) -> bool {
392 self.modify_response_fn.is_some()
393 }
394
395 pub fn modify_request(
403 &self,
404 scheme: &str,
405 authority: &Authority,
406 mutation: &mut RequestMutation,
407 ) {
408 if let Some(modify_request_fn) = &self.modify_request_fn {
409 modify_request_fn(scheme, authority, mutation);
410 }
411 }
412
413 pub fn modify_response(
416 &self,
417 scheme: &str,
418 authority: &Authority,
419 mutation: &mut ResponseMutation,
420 ) {
421 if let Some(modify_response_fn) = &self.modify_response_fn {
422 modify_response_fn(scheme, authority, mutation);
423 }
424 }
425
426 fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
428 ranges.iter().any(|range| range.contains(ip))
429 }
430
431 fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
433 ranges.iter().any(|range| range.contains(&port))
434 }
435}
436
437#[non_exhaustive]
444#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
445pub enum AclClassification {
446 AllowedUserAcl,
448 AllowedDefault,
450 DeniedUserAcl,
452 DeniedDefault,
454 Denied(String),
459 DeniedNotGlobal,
461}
462
463impl std::fmt::Display for AclClassification {
464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465 match self {
466 AclClassification::AllowedUserAcl => {
467 write!(f, "The entity is allowed according to the allowed ACL.")
468 }
469 AclClassification::AllowedDefault => write!(
470 f,
471 "The entity is allowed because the default is to allow if no ACL match is found."
472 ),
473 AclClassification::DeniedUserAcl => {
474 write!(f, "The entity is denied according to the denied ACL.")
475 }
476 AclClassification::DeniedNotGlobal => {
477 write!(f, "The ip is denied because it is not global.")
478 }
479 AclClassification::DeniedDefault => write!(
480 f,
481 "The entity is denied because the default is to deny if no ACL match is found."
482 ),
483 AclClassification::Denied(reason) => {
484 write!(f, "The entity is denied because {reason}.")
485 }
486 }
487 }
488}
489
490impl AclClassification {
491 pub fn is_allowed(&self) -> bool {
493 matches!(
494 self,
495 AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
496 )
497 }
498
499 pub fn is_denied(&self) -> bool {
501 matches!(
502 self,
503 AclClassification::DeniedUserAcl
504 | AclClassification::Denied(_)
505 | AclClassification::DeniedDefault
506 | AclClassification::DeniedNotGlobal
507 )
508 }
509}
510
511#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
513#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
514pub enum HttpRequestMethod {
515 CONNECT,
517 DELETE,
519 GET,
521 HEAD,
523 OPTIONS,
525 PATCH,
527 POST,
529 PUT,
531 TRACE,
533 OTHER(Box<str>),
535}
536
537impl From<&str> for HttpRequestMethod {
538 fn from(method: &str) -> Self {
539 match method {
540 "CONNECT" => HttpRequestMethod::CONNECT,
541 "DELETE" => HttpRequestMethod::DELETE,
542 "GET" => HttpRequestMethod::GET,
543 "HEAD" => HttpRequestMethod::HEAD,
544 "OPTIONS" => HttpRequestMethod::OPTIONS,
545 "PATCH" => HttpRequestMethod::PATCH,
546 "POST" => HttpRequestMethod::POST,
547 "PUT" => HttpRequestMethod::PUT,
548 "TRACE" => HttpRequestMethod::TRACE,
549 _ => HttpRequestMethod::OTHER(method.into()),
550 }
551 }
552}
553
554impl HttpRequestMethod {
555 pub fn as_str(&self) -> &str {
557 match self {
558 HttpRequestMethod::CONNECT => "CONNECT",
559 HttpRequestMethod::DELETE => "DELETE",
560 HttpRequestMethod::GET => "GET",
561 HttpRequestMethod::HEAD => "HEAD",
562 HttpRequestMethod::OPTIONS => "OPTIONS",
563 HttpRequestMethod::PATCH => "PATCH",
564 HttpRequestMethod::POST => "POST",
565 HttpRequestMethod::PUT => "PUT",
566 HttpRequestMethod::TRACE => "TRACE",
567 HttpRequestMethod::OTHER(other) => other,
568 }
569 }
570}
571
572#[derive(Clone, Default)]
580pub struct HttpAclHooks {
581 pub validate_fn: Option<ValidateFn>,
583 pub modify_request_fn: Option<ModifyRequestFn>,
585 pub modify_response_fn: Option<ModifyResponseFn>,
587}
588
589#[derive(Default, Clone)]
604#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
605pub struct HttpAclBuilder {
606 allow_http: bool,
607 allow_https: bool,
608 allowed_methods: Vec<HttpRequestMethod>,
609 denied_methods: Vec<HttpRequestMethod>,
610 allowed_hosts: Vec<String>,
611 denied_hosts: Vec<String>,
612 #[cfg_attr(feature = "serde", serde(skip))]
613 allowed_host_patterns: Vec<HostPattern>,
614 #[cfg_attr(feature = "serde", serde(skip))]
615 denied_host_patterns: Vec<HostPattern>,
616 allowed_port_ranges: Vec<RangeInclusive<u16>>,
617 denied_port_ranges: Vec<RangeInclusive<u16>>,
618 allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
619 denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
620 static_dns_mapping: HashMap<String, SocketAddr>,
621 trusted_static_dns_mapping: HashMap<String, SocketAddr>,
622 allowed_headers: HashMap<String, Option<String>>,
623 denied_headers: HashMap<String, Option<String>>,
624 allowed_url_paths: Vec<String>,
625 #[cfg_attr(feature = "serde", serde(skip))]
626 allowed_url_paths_router: Router<()>,
627 denied_url_paths: Vec<String>,
628 #[cfg_attr(feature = "serde", serde(skip))]
629 denied_url_paths_router: Router<()>,
630 allow_non_global_ip_ranges: bool,
631 method_acl_default: bool,
632 host_acl_default: bool,
633 port_acl_default: bool,
634 ip_acl_default: bool,
635 header_acl_default: bool,
636 url_path_acl_default: bool,
637}
638
639impl std::fmt::Debug for HttpAclBuilder {
640 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
641 f.debug_struct("HttpAclBuilder")
642 .field("allow_http", &self.allow_http)
643 .field("allow_https", &self.allow_https)
644 .field("allowed_methods", &self.allowed_methods)
645 .field("denied_methods", &self.denied_methods)
646 .field("allowed_hosts", &self.allowed_hosts)
647 .field("denied_hosts", &self.denied_hosts)
648 .field("allowed_port_ranges", &self.allowed_port_ranges)
649 .field("denied_port_ranges", &self.denied_port_ranges)
650 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
651 .field("denied_ip_ranges", &self.denied_ip_ranges)
652 .field("static_dns_mapping", &self.static_dns_mapping)
653 .field(
654 "trusted_static_dns_mapping",
655 &self.trusted_static_dns_mapping,
656 )
657 .field("allowed_headers", &self.allowed_headers)
658 .field("denied_headers", &self.denied_headers)
659 .field("allowed_url_paths", &self.allowed_url_paths)
660 .field("denied_url_paths", &self.denied_url_paths)
661 .field(
662 "allow_non_global_ip_ranges",
663 &self.allow_non_global_ip_ranges,
664 )
665 .field("method_acl_default", &self.method_acl_default)
666 .field("host_acl_default", &self.host_acl_default)
667 .field("port_acl_default", &self.port_acl_default)
668 .field("ip_acl_default", &self.ip_acl_default)
669 .field("header_acl_default", &self.header_acl_default)
670 .field("url_path_acl_default", &self.url_path_acl_default)
671 .finish()
672 }
673}
674
675impl PartialEq for HttpAclBuilder {
676 fn eq(&self, other: &Self) -> bool {
677 self.allow_http == other.allow_http
678 && self.allow_https == other.allow_https
679 && self.allowed_methods == other.allowed_methods
680 && self.denied_methods == other.denied_methods
681 && self.allowed_hosts == other.allowed_hosts
682 && self.denied_hosts == other.denied_hosts
683 && self.allowed_port_ranges == other.allowed_port_ranges
684 && self.denied_port_ranges == other.denied_port_ranges
685 && self.allowed_ip_ranges == other.allowed_ip_ranges
686 && self.denied_ip_ranges == other.denied_ip_ranges
687 && self.static_dns_mapping == other.static_dns_mapping
688 && self.trusted_static_dns_mapping == other.trusted_static_dns_mapping
689 && self.allowed_headers == other.allowed_headers
690 && self.denied_headers == other.denied_headers
691 && self.allowed_url_paths == other.allowed_url_paths
692 && self.denied_url_paths == other.denied_url_paths
693 && self.allow_non_global_ip_ranges == other.allow_non_global_ip_ranges
694 && self.method_acl_default == other.method_acl_default
695 && self.host_acl_default == other.host_acl_default
696 && self.port_acl_default == other.port_acl_default
697 && self.ip_acl_default == other.ip_acl_default
698 && self.header_acl_default == other.header_acl_default
699 && self.url_path_acl_default == other.url_path_acl_default
700 }
701}
702
703impl HttpAclBuilder {
704 pub fn new() -> Self {
706 Self {
707 allow_http: true,
708 allow_https: true,
709 allowed_methods: vec![
710 HttpRequestMethod::CONNECT,
711 HttpRequestMethod::DELETE,
712 HttpRequestMethod::GET,
713 HttpRequestMethod::HEAD,
714 HttpRequestMethod::OPTIONS,
715 HttpRequestMethod::PATCH,
716 HttpRequestMethod::POST,
717 HttpRequestMethod::PUT,
718 HttpRequestMethod::TRACE,
719 ],
720 denied_methods: Vec::new(),
721 allowed_hosts: Vec::new(),
722 denied_hosts: Vec::new(),
723 allowed_host_patterns: Vec::new(),
724 denied_host_patterns: Vec::new(),
725 allowed_port_ranges: vec![80..=80, 443..=443],
726 denied_port_ranges: Vec::new(),
727 allowed_ip_ranges: Vec::new(),
728 denied_ip_ranges: Vec::new(),
729 allowed_headers: HashMap::new(),
730 denied_headers: HashMap::new(),
731 allowed_url_paths: Vec::new(),
732 allowed_url_paths_router: Router::new(),
733 denied_url_paths: Vec::new(),
734 denied_url_paths_router: Router::new(),
735 allow_non_global_ip_ranges: false,
736 static_dns_mapping: HashMap::new(),
737 trusted_static_dns_mapping: HashMap::new(),
738 method_acl_default: false,
739 host_acl_default: false,
740 port_acl_default: false,
741 ip_acl_default: false,
742 header_acl_default: true,
743 url_path_acl_default: true,
744 }
745 }
746
747 pub fn http(mut self, allow: bool) -> Self {
749 self.allow_http = allow;
750 self
751 }
752
753 pub fn https(mut self, allow: bool) -> Self {
755 self.allow_https = allow;
756 self
757 }
758
759 pub fn non_global_ip_ranges(mut self, allow: bool) -> Self {
763 self.allow_non_global_ip_ranges = allow;
764 self
765 }
766
767 pub fn method_acl_default(mut self, allow: bool) -> Self {
769 self.method_acl_default = allow;
770 self
771 }
772
773 pub fn host_acl_default(mut self, allow: bool) -> Self {
775 self.host_acl_default = allow;
776 self
777 }
778
779 pub fn port_acl_default(mut self, allow: bool) -> Self {
781 self.port_acl_default = allow;
782 self
783 }
784
785 pub fn ip_acl_default(mut self, allow: bool) -> Self {
787 self.ip_acl_default = allow;
788 self
789 }
790
791 pub fn header_acl_default(mut self, allow: bool) -> Self {
793 self.header_acl_default = allow;
794 self
795 }
796
797 pub fn url_path_acl_default(mut self, allow: bool) -> Self {
799 self.url_path_acl_default = allow;
800 self
801 }
802
803 pub fn add_allowed_method(
807 mut self,
808 method: impl Into<HttpRequestMethod>,
809 ) -> Result<Self, AddError> {
810 let method = method.into();
811 if self.denied_methods.contains(&method) {
812 Err(AddError::AlreadyDeniedMethod(method))
813 } else if self.allowed_methods.contains(&method) {
814 Err(AddError::AlreadyAllowedMethod(method))
815 } else {
816 self.allowed_methods.push(method);
817 Ok(self)
818 }
819 }
820
821 pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
825 let method = method.into();
826 self.allowed_methods.retain(|m| m != &method);
827 self
828 }
829
830 pub fn allowed_methods(
834 mut self,
835 methods: Vec<impl Into<HttpRequestMethod>>,
836 ) -> Result<Self, AddError> {
837 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
838
839 for method in &methods {
840 if self.denied_methods.contains(method) {
841 return Err(AddError::AlreadyDeniedMethod(method.clone()));
842 }
843 }
844 self.allowed_methods = methods;
845 Ok(self)
846 }
847
848 pub fn clear_allowed_methods(mut self) -> Self {
850 self.allowed_methods.clear();
851 self
852 }
853
854 pub fn add_denied_method(
858 mut self,
859 method: impl Into<HttpRequestMethod>,
860 ) -> Result<Self, AddError> {
861 let method = method.into();
862 if self.allowed_methods.contains(&method) {
863 Err(AddError::AlreadyAllowedMethod(method))
864 } else if self.denied_methods.contains(&method) {
865 Err(AddError::AlreadyDeniedMethod(method))
866 } else {
867 self.denied_methods.push(method);
868 Ok(self)
869 }
870 }
871
872 pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
876 let method = method.into();
877 self.denied_methods.retain(|m| m != &method);
878 self
879 }
880
881 pub fn denied_methods(
885 mut self,
886 methods: Vec<impl Into<HttpRequestMethod>>,
887 ) -> Result<Self, AddError> {
888 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
889
890 for method in &methods {
891 if self.allowed_methods.contains(method) {
892 return Err(AddError::AlreadyAllowedMethod(method.clone()));
893 }
894 }
895 self.denied_methods = methods;
896 Ok(self)
897 }
898
899 pub fn clear_denied_methods(mut self) -> Self {
901 self.denied_methods.clear();
902 self
903 }
904
905 pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
919 let pattern = Self::validate_host_or_pattern(&host)?;
920
921 if self.denied_hosts.contains(&host) {
922 return Err(AddError::AlreadyDeniedHost(host));
923 }
924 if self.allowed_hosts.contains(&host) {
925 return Err(AddError::AlreadyAllowedHost(host));
926 }
927
928 if let Some(pattern) = pattern {
929 self.allowed_host_patterns.push(pattern);
930 }
931 self.allowed_hosts.push(host);
932 Ok(self)
933 }
934
935 pub fn remove_allowed_host(mut self, host: String) -> Self {
939 self.allowed_hosts.retain(|h| h != &host);
940 self.allowed_host_patterns = Self::compile_host_patterns(&self.allowed_hosts);
941 self
942 }
943
944 pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
950 let mut patterns = Vec::new();
951 for host in &hosts {
952 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
953 patterns.push(pattern);
954 }
955 if self.denied_hosts.contains(host) {
956 return Err(AddError::AlreadyDeniedHost(host.clone()));
957 }
958 }
959 self.allowed_host_patterns = patterns;
960 self.allowed_hosts = hosts;
961 Ok(self)
962 }
963
964 pub fn clear_allowed_hosts(mut self) -> Self {
966 self.allowed_hosts.clear();
967 self.allowed_host_patterns.clear();
968 self
969 }
970
971 pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
977 let pattern = Self::validate_host_or_pattern(&host)?;
978
979 if self.allowed_hosts.contains(&host) {
980 return Err(AddError::AlreadyAllowedHost(host));
981 }
982 if self.denied_hosts.contains(&host) {
983 return Err(AddError::AlreadyDeniedHost(host));
984 }
985
986 if let Some(pattern) = pattern {
987 self.denied_host_patterns.push(pattern);
988 }
989 self.denied_hosts.push(host);
990 Ok(self)
991 }
992
993 pub fn remove_denied_host(mut self, host: String) -> Self {
997 self.denied_hosts.retain(|h| h != &host);
998 self.denied_host_patterns = Self::compile_host_patterns(&self.denied_hosts);
999 self
1000 }
1001
1002 pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
1008 let mut patterns = Vec::new();
1009 for host in &hosts {
1010 if let Some(pattern) = Self::validate_host_or_pattern(host)? {
1011 patterns.push(pattern);
1012 }
1013 if self.allowed_hosts.contains(host) {
1014 return Err(AddError::AlreadyAllowedHost(host.clone()));
1015 }
1016 }
1017 self.denied_host_patterns = patterns;
1018 self.denied_hosts = hosts;
1019 Ok(self)
1020 }
1021
1022 pub fn clear_denied_hosts(mut self) -> Self {
1024 self.denied_hosts.clear();
1025 self.denied_host_patterns.clear();
1026 self
1027 }
1028
1029 fn validate_host_or_pattern(host: &str) -> Result<Option<HostPattern>, AddError> {
1032 if is_wildcard_host(host) {
1033 match HostPattern::parse(host) {
1034 Some(pattern) => Ok(Some(pattern)),
1035 None => Err(AddError::InvalidEntity(host.to_string())),
1036 }
1037 } else if utils::authority::is_valid_host(host) {
1038 Ok(None)
1039 } else {
1040 Err(AddError::InvalidEntity(host.to_string()))
1041 }
1042 }
1043
1044 fn compile_host_patterns(hosts: &[String]) -> Vec<HostPattern> {
1046 hosts
1047 .iter()
1048 .filter(|h| is_wildcard_host(h))
1049 .filter_map(|h| HostPattern::parse(h))
1050 .collect()
1051 }
1052
1053 pub fn add_allowed_port_range(
1055 mut self,
1056 port_range: RangeInclusive<u16>,
1057 ) -> Result<Self, AddError> {
1058 if self.denied_port_ranges.contains(&port_range) {
1059 Err(AddError::AlreadyDeniedPortRange(port_range))
1060 } else if self.allowed_port_ranges.contains(&port_range) {
1061 Err(AddError::AlreadyAllowedPortRange(port_range))
1062 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
1063 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
1064 {
1065 Err(AddError::Overlaps(format!("{port_range:?}")))
1066 } else {
1067 self.allowed_port_ranges.push(port_range);
1068 Ok(self)
1069 }
1070 }
1071
1072 pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1074 self.allowed_port_ranges.retain(|p| p != &port_range);
1075 self
1076 }
1077
1078 pub fn allowed_port_ranges(
1080 mut self,
1081 port_ranges: Vec<RangeInclusive<u16>>,
1082 ) -> Result<Self, AddError> {
1083 for (i, port_range) in port_ranges.iter().enumerate() {
1084 if self.denied_port_ranges.contains(port_range) {
1085 return Err(AddError::AlreadyDeniedPortRange(port_range.clone()));
1086 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1087 || utils::range_overlaps(&self.denied_port_ranges, port_range, None)
1088 {
1089 return Err(AddError::Overlaps(format!("{port_range:?}")));
1090 }
1091 }
1092 self.allowed_port_ranges = port_ranges;
1093 Ok(self)
1094 }
1095
1096 pub fn clear_allowed_port_ranges(mut self) -> Self {
1098 self.allowed_port_ranges.clear();
1099 self
1100 }
1101
1102 pub fn add_denied_port_range(
1104 mut self,
1105 port_range: RangeInclusive<u16>,
1106 ) -> Result<Self, AddError> {
1107 if self.allowed_port_ranges.contains(&port_range) {
1108 Err(AddError::AlreadyAllowedPortRange(port_range))
1109 } else if self.denied_port_ranges.contains(&port_range) {
1110 Err(AddError::AlreadyDeniedPortRange(port_range))
1111 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range, None)
1112 || utils::range_overlaps(&self.denied_port_ranges, &port_range, None)
1113 {
1114 Err(AddError::Overlaps(format!("{port_range:?}")))
1115 } else {
1116 self.denied_port_ranges.push(port_range);
1117 Ok(self)
1118 }
1119 }
1120
1121 pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
1123 self.denied_port_ranges.retain(|p| p != &port_range);
1124 self
1125 }
1126
1127 pub fn denied_port_ranges(
1129 mut self,
1130 port_ranges: Vec<RangeInclusive<u16>>,
1131 ) -> Result<Self, AddError> {
1132 for (i, port_range) in port_ranges.iter().enumerate() {
1133 if self.allowed_port_ranges.contains(port_range) {
1134 return Err(AddError::AlreadyAllowedPortRange(port_range.clone()));
1135 } else if utils::range_overlaps(&port_ranges, port_range, Some(i))
1136 || utils::range_overlaps(&self.allowed_port_ranges, port_range, None)
1137 {
1138 return Err(AddError::Overlaps(format!("{port_range:?}")));
1139 }
1140 }
1141 self.denied_port_ranges = port_ranges;
1142 Ok(self)
1143 }
1144
1145 pub fn clear_denied_port_ranges(mut self) -> Self {
1147 self.denied_port_ranges.clear();
1148 self
1149 }
1150
1151 pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1153 let ip_range = ip_range
1154 .into_range()
1155 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1156 if self.denied_ip_ranges.contains(&ip_range) {
1157 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1158 } else if self.allowed_ip_ranges.contains(&ip_range) {
1159 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1160 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1161 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1162 {
1163 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1164 }
1165 self.allowed_ip_ranges.push(ip_range);
1166 Ok(self)
1167 }
1168
1169 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
1171 mut self,
1172 ip_range: Ip,
1173 ) -> Result<Self, AddError> {
1174 let ip_range = ip_range
1175 .into_range()
1176 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1177 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
1178 Ok(self)
1179 }
1180
1181 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
1183 mut self,
1184 ip_ranges: Vec<Ip>,
1185 ) -> Result<Self, AddError> {
1186 let ip_ranges = ip_ranges
1187 .into_iter()
1188 .map(|ip| ip.into_range())
1189 .collect::<Option<Vec<_>>>()
1190 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1191 for (i, ip_range) in ip_ranges.iter().enumerate() {
1192 if self.denied_ip_ranges.contains(ip_range) {
1193 return Err(AddError::AlreadyDeniedIpRange(ip_range.clone()));
1194 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1195 || utils::range_overlaps(&self.denied_ip_ranges, ip_range, None)
1196 {
1197 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1198 }
1199 }
1200 self.allowed_ip_ranges = ip_ranges;
1201 Ok(self)
1202 }
1203
1204 pub fn clear_allowed_ip_ranges(mut self) -> Self {
1206 self.allowed_ip_ranges.clear();
1207 self
1208 }
1209
1210 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
1212 let ip_range = ip_range
1213 .into_range()
1214 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1215 if self.allowed_ip_ranges.contains(&ip_range) {
1216 return Err(AddError::AlreadyAllowedIpRange(ip_range));
1217 } else if self.denied_ip_ranges.contains(&ip_range) {
1218 return Err(AddError::AlreadyDeniedIpRange(ip_range));
1219 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range, None)
1220 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range, None)
1221 {
1222 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1223 }
1224 self.denied_ip_ranges.push(ip_range);
1225 Ok(self)
1226 }
1227
1228 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
1230 mut self,
1231 ip_range: Ip,
1232 ) -> Result<Self, AddError> {
1233 let ip_range = ip_range
1234 .into_range()
1235 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1236 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
1237 Ok(self)
1238 }
1239
1240 pub fn denied_ip_ranges<Ip: IntoIpRange>(
1242 mut self,
1243 ip_ranges: Vec<Ip>,
1244 ) -> Result<Self, AddError> {
1245 let ip_ranges = ip_ranges
1246 .into_iter()
1247 .map(|ip| ip.into_range())
1248 .collect::<Option<Vec<_>>>()
1249 .ok_or_else(|| AddError::InvalidEntity("Invalid IP range".to_string()))?;
1250 for (i, ip_range) in ip_ranges.iter().enumerate() {
1251 if self.allowed_ip_ranges.contains(ip_range) {
1252 return Err(AddError::AlreadyAllowedIpRange(ip_range.clone()));
1253 } else if utils::range_overlaps(&ip_ranges, ip_range, Some(i))
1254 || utils::range_overlaps(&self.allowed_ip_ranges, ip_range, None)
1255 {
1256 return Err(AddError::Overlaps(format!("{ip_range:?}")));
1257 }
1258 }
1259 self.denied_ip_ranges = ip_ranges;
1260 Ok(self)
1261 }
1262
1263 pub fn clear_denied_ip_ranges(mut self) -> Self {
1265 self.denied_ip_ranges.clear();
1266 self
1267 }
1268
1269 pub fn add_static_dns_mapping(
1277 mut self,
1278 host: String,
1279 sock_addr: SocketAddr,
1280 ) -> Result<Self, AddError> {
1281 if !utils::authority::is_valid_host(&host) {
1282 return Err(AddError::InvalidEntity(host));
1283 }
1284 if self.trusted_static_dns_mapping.contains_key(&host) {
1285 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1286 host, sock_addr,
1287 ));
1288 }
1289 if let Entry::Vacant(e) = self.static_dns_mapping.entry(host.clone()) {
1290 e.insert(sock_addr);
1291 Ok(self)
1292 } else {
1293 Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr))
1294 }
1295 }
1296
1297 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
1301 self.static_dns_mapping.remove(host);
1302 self
1303 }
1304
1305 pub fn static_dns_mappings(
1309 mut self,
1310 mappings: HashMap<String, SocketAddr>,
1311 ) -> Result<Self, AddError> {
1312 for (host, ip) in &mappings {
1313 if !utils::authority::is_valid_host(host) {
1314 return Err(AddError::InvalidEntity(host.clone()));
1315 }
1316 if self.trusted_static_dns_mapping.contains_key(host) {
1317 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1318 host.clone(),
1319 *ip,
1320 ));
1321 }
1322 if self.static_dns_mapping.contains_key(host) {
1323 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1324 }
1325 self.static_dns_mapping.insert(host.to_string(), *ip);
1326 }
1327 Ok(self)
1328 }
1329
1330 pub fn clear_static_dns_mappings(mut self) -> Self {
1332 self.static_dns_mapping.clear();
1333 self
1334 }
1335
1336 pub fn add_trusted_static_dns_mapping(
1345 mut self,
1346 host: String,
1347 sock_addr: SocketAddr,
1348 ) -> Result<Self, AddError> {
1349 if !utils::authority::is_valid_host(&host) {
1350 return Err(AddError::InvalidEntity(host));
1351 }
1352 if self.static_dns_mapping.contains_key(&host) {
1353 return Err(AddError::AlreadyPresentStaticDnsMapping(host, sock_addr));
1354 }
1355 if let Entry::Vacant(e) = self.trusted_static_dns_mapping.entry(host.clone()) {
1356 e.insert(sock_addr);
1357 Ok(self)
1358 } else {
1359 Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1360 host, sock_addr,
1361 ))
1362 }
1363 }
1364
1365 pub fn remove_trusted_static_dns_mapping(mut self, host: &str) -> Self {
1369 self.trusted_static_dns_mapping.remove(host);
1370 self
1371 }
1372
1373 pub fn trusted_static_dns_mappings(
1377 mut self,
1378 mappings: HashMap<String, SocketAddr>,
1379 ) -> Result<Self, AddError> {
1380 for (host, ip) in &mappings {
1381 if !utils::authority::is_valid_host(host) {
1382 return Err(AddError::InvalidEntity(host.clone()));
1383 }
1384 if self.static_dns_mapping.contains_key(host) {
1385 return Err(AddError::AlreadyPresentStaticDnsMapping(host.clone(), *ip));
1386 }
1387 if self.trusted_static_dns_mapping.contains_key(host) {
1388 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1389 host.clone(),
1390 *ip,
1391 ));
1392 }
1393 self.trusted_static_dns_mapping
1394 .insert(host.to_string(), *ip);
1395 }
1396 Ok(self)
1397 }
1398
1399 pub fn clear_trusted_static_dns_mappings(mut self) -> Self {
1401 self.trusted_static_dns_mapping.clear();
1402 self
1403 }
1404
1405 pub fn add_allowed_header(
1411 mut self,
1412 header: String,
1413 value: Option<String>,
1414 ) -> Result<Self, AddError> {
1415 if self.denied_headers.contains_key(&header) {
1416 Err(AddError::AlreadyDeniedHeader(header, value.clone()))
1417 } else if let Entry::Vacant(e) = self.allowed_headers.entry(header.clone()) {
1418 e.insert(value);
1419 Ok(self)
1420 } else {
1421 Err(AddError::AlreadyAllowedHeader(header, value))
1422 }
1423 }
1424
1425 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1429 self.allowed_headers.remove(header);
1430 self
1431 }
1432
1433 pub fn allowed_headers(
1437 mut self,
1438 headers: HashMap<String, Option<String>>,
1439 ) -> Result<Self, AddError> {
1440 for (header, value) in &headers {
1441 if self.denied_headers.contains_key(header) {
1442 return Err(AddError::AlreadyDeniedHeader(header.clone(), value.clone()));
1443 }
1444 }
1445 self.allowed_headers = headers;
1446 Ok(self)
1447 }
1448
1449 pub fn clear_allowed_headers(mut self) -> Self {
1451 self.allowed_headers.clear();
1452 self
1453 }
1454
1455 pub fn add_denied_header(
1461 mut self,
1462 header: String,
1463 value: Option<String>,
1464 ) -> Result<Self, AddError> {
1465 if self.allowed_headers.contains_key(&header) {
1466 Err(AddError::AlreadyAllowedHeader(header, value.clone()))
1467 } else if let Entry::Vacant(e) = self.denied_headers.entry(header.clone()) {
1468 e.insert(value);
1469 Ok(self)
1470 } else {
1471 Err(AddError::AlreadyDeniedHeader(header, value))
1472 }
1473 }
1474
1475 pub fn remove_denied_header(mut self, header: &str) -> Self {
1479 self.denied_headers.remove(header);
1480 self
1481 }
1482
1483 pub fn denied_headers(
1487 mut self,
1488 headers: HashMap<String, Option<String>>,
1489 ) -> Result<Self, AddError> {
1490 for (header, value) in &headers {
1491 if self.allowed_headers.contains_key(header) {
1492 return Err(AddError::AlreadyAllowedHeader(
1493 header.clone(),
1494 value.clone(),
1495 ));
1496 }
1497 }
1498 self.denied_headers = headers;
1499 Ok(self)
1500 }
1501
1502 pub fn clear_denied_headers(mut self) -> Self {
1504 self.denied_headers.clear();
1505 self
1506 }
1507
1508 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1512 if self.denied_url_paths.contains(&url_path)
1513 || self.denied_url_paths_router.at(&url_path).is_ok()
1514 {
1515 Err(AddError::AlreadyDeniedUrlPath(url_path))
1516 } else if self.allowed_url_paths.contains(&url_path)
1517 || self.allowed_url_paths_router.at(&url_path).is_ok()
1518 {
1519 Err(AddError::AlreadyAllowedUrlPath(url_path))
1520 } else {
1521 self.allowed_url_paths.push(url_path.clone());
1522 self.allowed_url_paths_router
1523 .insert(url_path, ())
1524 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1525 Ok(self)
1526 }
1527 }
1528
1529 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1533 self.allowed_url_paths.retain(|p| p != url_path);
1534 self.allowed_url_paths_router = {
1535 let mut router = Router::new();
1536 for url_path in &self.allowed_url_paths {
1537 router
1538 .insert(url_path.clone(), ())
1539 .expect("failed to insert url path");
1540 }
1541 router
1542 };
1543 self
1544 }
1545
1546 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1550 for url_path in &url_paths {
1551 if self.denied_url_paths.contains(url_path)
1552 || self.denied_url_paths_router.at(url_path).is_ok()
1553 {
1554 return Err(AddError::AlreadyDeniedUrlPath(url_path.clone()));
1555 }
1556 }
1557 self.allowed_url_paths_router = Router::new();
1558 for url_path in &url_paths {
1559 self.allowed_url_paths_router
1560 .insert(url_path.clone(), ())
1561 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1562 }
1563 self.allowed_url_paths = url_paths;
1564 Ok(self)
1565 }
1566
1567 pub fn clear_allowed_url_paths(mut self) -> Self {
1569 self.allowed_url_paths.clear();
1570 self.allowed_url_paths_router = Router::new();
1571 self
1572 }
1573
1574 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1578 if self.allowed_url_paths.contains(&url_path)
1579 || self.allowed_url_paths_router.at(&url_path).is_ok()
1580 {
1581 Err(AddError::AlreadyAllowedUrlPath(url_path))
1582 } else if self.denied_url_paths.contains(&url_path)
1583 || self.denied_url_paths_router.at(&url_path).is_ok()
1584 {
1585 Err(AddError::AlreadyDeniedUrlPath(url_path))
1586 } else {
1587 self.denied_url_paths.push(url_path.clone());
1588 self.denied_url_paths_router
1589 .insert(url_path, ())
1590 .map_err(|_| AddError::InvalidEntity("Invalid URL path".to_string()))?;
1591 Ok(self)
1592 }
1593 }
1594
1595 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1599 self.denied_url_paths.retain(|p| p != url_path);
1600 self.denied_url_paths_router = {
1601 let mut router = Router::new();
1602 for url_path in &self.denied_url_paths {
1603 router
1604 .insert(url_path.clone(), ())
1605 .expect("failed to insert url path");
1606 }
1607 router
1608 };
1609 self
1610 }
1611
1612 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1616 for url_path in &url_paths {
1617 if self.allowed_url_paths.contains(url_path)
1618 || self.allowed_url_paths_router.at(url_path).is_ok()
1619 {
1620 return Err(AddError::AlreadyAllowedUrlPath(url_path.clone()));
1621 }
1622 }
1623 self.denied_url_paths_router = Router::new();
1624 for url_path in &url_paths {
1625 self.denied_url_paths_router
1626 .insert(url_path.clone(), ())
1627 .map_err(|_| AddError::InvalidEntity(format!("Invalid URL path: {url_path}")))?;
1628 }
1629 self.denied_url_paths = url_paths;
1630 Ok(self)
1631 }
1632
1633 pub fn clear_denied_url_paths(mut self) -> Self {
1635 self.denied_url_paths.clear();
1636 self.denied_url_paths_router = Router::new();
1637 self
1638 }
1639
1640 pub fn build(self) -> HttpAcl {
1647 self.build_full(HttpAclHooks::default())
1648 }
1649
1650 pub fn build_full(self, hooks: HttpAclHooks) -> HttpAcl {
1657 HttpAcl {
1658 allow_http: self.allow_http,
1659 allow_https: self.allow_https,
1660 allowed_methods: self.allowed_methods.into_iter().collect(),
1661 denied_methods: self.denied_methods.into_iter().collect(),
1662 allowed_hosts: self
1663 .allowed_hosts
1664 .into_iter()
1665 .filter(|h| !is_wildcard_host(h))
1666 .map(|x| x.into_boxed_str())
1667 .collect(),
1668 denied_hosts: self
1669 .denied_hosts
1670 .into_iter()
1671 .filter(|h| !is_wildcard_host(h))
1672 .map(|x| x.into_boxed_str())
1673 .collect(),
1674 allowed_host_patterns: self.allowed_host_patterns.into_boxed_slice(),
1675 denied_host_patterns: self.denied_host_patterns.into_boxed_slice(),
1676 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1677 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1678 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1679 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1680 allowed_headers: self
1681 .allowed_headers
1682 .into_iter()
1683 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1684 .collect(),
1685 denied_headers: self
1686 .denied_headers
1687 .into_iter()
1688 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1689 .collect(),
1690 allowed_url_paths_router: self.allowed_url_paths_router,
1691 denied_url_paths_router: self.denied_url_paths_router,
1692 static_dns_mapping: self
1693 .static_dns_mapping
1694 .into_iter()
1695 .map(|(k, v)| (k.into_boxed_str(), v))
1696 .collect(),
1697 trusted_static_dns_mapping: self
1698 .trusted_static_dns_mapping
1699 .into_iter()
1700 .map(|(k, v)| (k.into_boxed_str(), v))
1701 .collect(),
1702 validate_fn: hooks.validate_fn,
1703 modify_request_fn: hooks.modify_request_fn,
1704 modify_response_fn: hooks.modify_response_fn,
1705 allow_non_global_ip_ranges: self.allow_non_global_ip_ranges,
1706 method_acl_default: self.method_acl_default,
1707 host_acl_default: self.host_acl_default,
1708 port_acl_default: self.port_acl_default,
1709 ip_acl_default: self.ip_acl_default,
1710 header_acl_default: self.header_acl_default,
1711 url_path_acl_default: self.url_path_acl_default,
1712 }
1713 }
1714
1715 pub fn try_build_full(mut self, hooks: HttpAclHooks) -> Result<HttpAcl, AddError> {
1732 if !utils::has_unique_elements(&self.allowed_methods) {
1733 return Err(AddError::NotUnique(
1734 "Allowed methods must be unique.".to_string(),
1735 ));
1736 }
1737 for method in &self.allowed_methods {
1738 if self.denied_methods.contains(method) {
1739 return Err(AddError::BothAllowedAndDenied(format!(
1740 "Method `{}`",
1741 method.as_str()
1742 )));
1743 }
1744 }
1745 if !utils::has_unique_elements(&self.denied_methods) {
1746 return Err(AddError::NotUnique(
1747 "Denied methods must be unique.".to_string(),
1748 ));
1749 }
1750 for method in &self.denied_methods {
1751 if self.allowed_methods.contains(method) {
1752 return Err(AddError::BothAllowedAndDenied(format!(
1753 "Method `{}`",
1754 method.as_str()
1755 )));
1756 }
1757 }
1758 if !utils::has_unique_elements(&self.allowed_hosts) {
1759 return Err(AddError::NotUnique(
1760 "Allowed hosts must be unique.".to_string(),
1761 ));
1762 }
1763 for host in &self.allowed_hosts {
1764 if is_wildcard_host(host) {
1765 match HostPattern::parse(host) {
1766 Some(pattern) => {
1767 if !self.allowed_host_patterns.contains(&pattern) {
1768 self.allowed_host_patterns.push(pattern);
1769 }
1770 }
1771 None => return Err(AddError::InvalidEntity(host.to_string())),
1772 }
1773 } else if !utils::authority::is_valid_host(host) {
1774 return Err(AddError::InvalidEntity(host.to_string()));
1775 }
1776 if self.denied_hosts.contains(host) {
1777 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1778 }
1779 }
1780 if !utils::has_unique_elements(&self.denied_hosts) {
1781 return Err(AddError::NotUnique(
1782 "Denied hosts must be unique.".to_string(),
1783 ));
1784 }
1785 for host in &self.denied_hosts {
1786 if is_wildcard_host(host) {
1787 match HostPattern::parse(host) {
1788 Some(pattern) => {
1789 if !self.denied_host_patterns.contains(&pattern) {
1790 self.denied_host_patterns.push(pattern);
1791 }
1792 }
1793 None => return Err(AddError::InvalidEntity(host.to_string())),
1794 }
1795 } else if !utils::authority::is_valid_host(host) {
1796 return Err(AddError::InvalidEntity(host.to_string()));
1797 }
1798 if self.allowed_hosts.contains(host) {
1799 return Err(AddError::BothAllowedAndDenied(format!("Host `{host}`")));
1800 }
1801 }
1802 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1803 return Err(AddError::NotUnique(
1804 "Allowed port ranges must be unique.".to_string(),
1805 ));
1806 }
1807 if utils::has_overlapping_ranges(&self.allowed_port_ranges) {
1808 return Err(AddError::Overlaps(
1809 "Allowed port ranges must not overlap.".to_string(),
1810 ));
1811 }
1812 for port_range in &self.allowed_port_ranges {
1813 if self.denied_port_ranges.contains(port_range) {
1814 return Err(AddError::BothAllowedAndDenied(format!(
1815 "Port range `{port_range:?}`"
1816 )));
1817 }
1818 }
1819 if !utils::has_unique_elements(&self.denied_port_ranges) {
1820 return Err(AddError::NotUnique(
1821 "Denied port ranges must be unique.".to_string(),
1822 ));
1823 }
1824 if utils::has_overlapping_ranges(&self.denied_port_ranges) {
1825 return Err(AddError::Overlaps(
1826 "Denied port ranges must not overlap.".to_string(),
1827 ));
1828 }
1829 for port_range in &self.denied_port_ranges {
1830 if self.allowed_port_ranges.contains(port_range) {
1831 return Err(AddError::BothAllowedAndDenied(format!(
1832 "Port range `{port_range:?}`"
1833 )));
1834 }
1835 }
1836 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1837 return Err(AddError::NotUnique(
1838 "Allowed IP ranges must be unique.".to_string(),
1839 ));
1840 }
1841 if utils::has_overlapping_ranges(&self.allowed_ip_ranges) {
1842 return Err(AddError::Overlaps(
1843 "Allowed IP ranges must not overlap.".to_string(),
1844 ));
1845 }
1846 for ip_range in &self.allowed_ip_ranges {
1847 if self.denied_ip_ranges.contains(ip_range) {
1848 return Err(AddError::BothAllowedAndDenied(format!(
1849 "IP range `{ip_range:?}`"
1850 )));
1851 }
1852
1853 if (!utils::ip::is_global_ip(ip_range.start())
1854 || !utils::ip::is_global_ip(ip_range.end()))
1855 && !self.allow_non_global_ip_ranges
1856 {
1857 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1858 }
1859 }
1860 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1861 return Err(AddError::NotUnique(
1862 "Denied IP ranges must be unique.".to_string(),
1863 ));
1864 }
1865 if utils::has_overlapping_ranges(&self.denied_ip_ranges) {
1866 return Err(AddError::Overlaps(
1867 "Denied IP ranges must not overlap.".to_string(),
1868 ));
1869 }
1870 for ip_range in &self.denied_ip_ranges {
1871 if self.allowed_ip_ranges.contains(ip_range) {
1872 return Err(AddError::BothAllowedAndDenied(format!(
1873 "IP range `{ip_range:?}`"
1874 )));
1875 }
1876
1877 if (!utils::ip::is_global_ip(ip_range.start())
1878 || !utils::ip::is_global_ip(ip_range.end()))
1879 && !self.allow_non_global_ip_ranges
1880 {
1881 return Err(AddError::NonGlobalIpRange(ip_range.clone()));
1882 }
1883 }
1884 if !utils::has_unique_elements(&self.static_dns_mapping) {
1885 return Err(AddError::NotUnique(
1886 "Static DNS mapping must be unique.".to_string(),
1887 ));
1888 }
1889 for (host, addr) in &self.static_dns_mapping {
1890 if !utils::authority::is_valid_host(host) {
1891 return Err(AddError::InvalidEntity(host.to_string()));
1892 }
1893 if self.trusted_static_dns_mapping.contains_key(host) {
1894 return Err(AddError::AlreadyPresentTrustedStaticDnsMapping(
1895 host.to_string(),
1896 *addr,
1897 ));
1898 }
1899 }
1900 if !utils::has_unique_elements(&self.trusted_static_dns_mapping) {
1901 return Err(AddError::NotUnique(
1902 "Trusted static DNS mapping must be unique.".to_string(),
1903 ));
1904 }
1905 for host in self.trusted_static_dns_mapping.keys() {
1906 if !utils::authority::is_valid_host(host) {
1907 return Err(AddError::InvalidEntity(host.to_string()));
1908 }
1909 }
1910 if !utils::has_unique_elements(&self.allowed_url_paths) {
1911 return Err(AddError::NotUnique(
1912 "Allowed URL paths must be unique.".to_string(),
1913 ));
1914 }
1915 for url_path in &self.allowed_url_paths {
1916 if self.denied_url_paths.contains(url_path)
1917 || self.denied_url_paths_router.at(url_path).is_ok()
1918 {
1919 return Err(AddError::BothAllowedAndDenied(format!(
1920 "URL path `{url_path}`"
1921 )));
1922 } else if self.allowed_url_paths_router.at(url_path).is_err() {
1923 self.allowed_url_paths_router
1924 .insert(url_path.clone(), ())
1925 .map_err(|_| {
1926 AddError::InvalidEntity(format!(
1927 "Failed to insert allowed URL path `{url_path}`."
1928 ))
1929 })?;
1930 }
1931 }
1932 if !utils::has_unique_elements(&self.denied_url_paths) {
1933 return Err(AddError::NotUnique(
1934 "Denied URL paths must be unique.".to_string(),
1935 ));
1936 }
1937 for url_path in &self.denied_url_paths {
1938 if self.allowed_url_paths.contains(url_path)
1939 || self.allowed_url_paths_router.at(url_path).is_ok()
1940 {
1941 return Err(AddError::BothAllowedAndDenied(format!(
1942 "URL path `{url_path}`"
1943 )));
1944 } else if self.denied_url_paths_router.at(url_path).is_err() {
1945 self.denied_url_paths_router
1946 .insert(url_path.clone(), ())
1947 .map_err(|_| {
1948 AddError::InvalidEntity(format!(
1949 "Failed to insert denied URL path `{url_path}`."
1950 ))
1951 })?;
1952 }
1953 }
1954 Ok(self.build_full(hooks))
1955 }
1956
1957 pub fn try_build(self) -> Result<HttpAcl, AddError> {
1961 self.try_build_full(HttpAclHooks::default())
1962 }
1963}