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