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