1#[cfg(feature = "hashbrown")]
5use hashbrown::HashMap;
6#[cfg(not(feature = "hashbrown"))]
7use std::collections::HashMap;
8use std::hash::Hash;
9use std::net::{IpAddr, SocketAddr};
10use std::ops::RangeInclusive;
11
12use matchit::Router;
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16use crate::{
17 error::AddError,
18 utils::{self, IntoIpRange},
19};
20
21#[derive(Clone)]
22pub struct HttpAcl {
24 allow_http: bool,
25 allow_https: bool,
26 allowed_methods: Box<[HttpRequestMethod]>,
27 denied_methods: Box<[HttpRequestMethod]>,
28 allowed_hosts: Box<[Box<str>]>,
29 denied_hosts: Box<[Box<str>]>,
30 allowed_port_ranges: Box<[RangeInclusive<u16>]>,
31 denied_port_ranges: Box<[RangeInclusive<u16>]>,
32 allowed_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
33 denied_ip_ranges: Box<[RangeInclusive<IpAddr>]>,
34 static_dns_mapping: HashMap<Box<str>, SocketAddr>,
35 allowed_headers: HashMap<Box<str>, Option<Box<str>>>,
36 denied_headers: HashMap<Box<str>, Option<Box<str>>>,
37 allowed_url_paths_router: Router<()>,
38 denied_url_paths_router: Router<()>,
39 allow_private_ip_ranges: bool,
40 method_acl_default: bool,
41 host_acl_default: bool,
42 port_acl_default: bool,
43 ip_acl_default: bool,
44 header_acl_default: bool,
45 url_path_acl_default: bool,
46}
47
48impl std::fmt::Debug for HttpAcl {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 f.debug_struct("HttpAcl")
51 .field("allow_http", &self.allow_http)
52 .field("allow_https", &self.allow_https)
53 .field("allowed_methods", &self.allowed_methods)
54 .field("denied_methods", &self.denied_methods)
55 .field("allowed_hosts", &self.allowed_hosts)
56 .field("denied_hosts", &self.denied_hosts)
57 .field("allowed_port_ranges", &self.allowed_port_ranges)
58 .field("denied_port_ranges", &self.denied_port_ranges)
59 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
60 .field("denied_ip_ranges", &self.denied_ip_ranges)
61 .field("static_dns_mapping", &self.static_dns_mapping)
62 .field("allowed_headers", &self.allowed_headers)
63 .field("denied_headers", &self.denied_headers)
64 .field("allow_private_ip_ranges", &self.allow_private_ip_ranges)
65 .field("method_acl_default", &self.method_acl_default)
66 .field("host_acl_default", &self.host_acl_default)
67 .field("port_acl_default", &self.port_acl_default)
68 .field("ip_acl_default", &self.ip_acl_default)
69 .field("header_acl_default", &self.header_acl_default)
70 .field("url_path_acl_default", &self.url_path_acl_default)
71 .finish()
72 }
73}
74
75impl PartialEq for HttpAcl {
76 fn eq(&self, other: &Self) -> bool {
77 self.allow_http == other.allow_http
78 && self.allow_https == other.allow_https
79 && self.allowed_methods == other.allowed_methods
80 && self.denied_methods == other.denied_methods
81 && self.allowed_hosts == other.allowed_hosts
82 && self.denied_hosts == other.denied_hosts
83 && self.allowed_port_ranges == other.allowed_port_ranges
84 && self.denied_port_ranges == other.denied_port_ranges
85 && self.allowed_ip_ranges == other.allowed_ip_ranges
86 && self.denied_ip_ranges == other.denied_ip_ranges
87 && self.static_dns_mapping == other.static_dns_mapping
88 && self.allowed_headers == other.allowed_headers
89 && self.denied_headers == other.denied_headers
90 && self.allow_private_ip_ranges == other.allow_private_ip_ranges
91 && self.method_acl_default == other.method_acl_default
92 && self.host_acl_default == other.host_acl_default
93 && self.port_acl_default == other.port_acl_default
94 && self.ip_acl_default == other.ip_acl_default
95 && self.header_acl_default == other.header_acl_default
96 && self.url_path_acl_default == other.url_path_acl_default
97 }
98}
99
100impl std::default::Default for HttpAcl {
101 fn default() -> Self {
102 Self {
103 allow_http: true,
104 allow_https: true,
105 allowed_methods: vec![
106 HttpRequestMethod::CONNECT,
107 HttpRequestMethod::DELETE,
108 HttpRequestMethod::GET,
109 HttpRequestMethod::HEAD,
110 HttpRequestMethod::OPTIONS,
111 HttpRequestMethod::PATCH,
112 HttpRequestMethod::POST,
113 HttpRequestMethod::PUT,
114 HttpRequestMethod::TRACE,
115 ]
116 .into_boxed_slice(),
117 denied_methods: Vec::new().into_boxed_slice(),
118 allowed_hosts: Vec::new().into_boxed_slice(),
119 denied_hosts: Vec::new().into_boxed_slice(),
120 allowed_port_ranges: vec![80..=80, 443..=443].into_boxed_slice(),
121 denied_port_ranges: Vec::new().into_boxed_slice(),
122 allowed_ip_ranges: Vec::new().into_boxed_slice(),
123 denied_ip_ranges: Vec::new().into_boxed_slice(),
124 static_dns_mapping: HashMap::new(),
125 allowed_headers: HashMap::new(),
126 denied_headers: HashMap::new(),
127 allowed_url_paths_router: Router::new(),
128 denied_url_paths_router: Router::new(),
129 allow_private_ip_ranges: false,
130 method_acl_default: false,
131 host_acl_default: false,
132 port_acl_default: false,
133 ip_acl_default: false,
134 header_acl_default: false,
135 url_path_acl_default: true,
136 }
137 }
138}
139
140impl HttpAcl {
141 pub fn builder() -> HttpAclBuilder {
143 HttpAclBuilder::new()
144 }
145
146 pub fn is_scheme_allowed(&self, scheme: &str) -> AclClassification {
148 if scheme == "http" && self.allow_http || scheme == "https" && self.allow_https {
149 AclClassification::AllowedUserAcl
150 } else {
151 AclClassification::DeniedUserAcl
152 }
153 }
154
155 pub fn is_method_allowed(&self, method: impl Into<HttpRequestMethod>) -> AclClassification {
157 let method = method.into();
158 if self.allowed_methods.contains(&method) {
159 AclClassification::AllowedUserAcl
160 } else if self.denied_methods.contains(&method) {
161 AclClassification::DeniedUserAcl
162 } else if self.method_acl_default {
163 AclClassification::AllowedDefault
164 } else {
165 AclClassification::DeniedDefault
166 }
167 }
168
169 pub fn is_host_allowed(&self, host: &str) -> AclClassification {
171 if self.denied_hosts.iter().any(|h| h.as_ref() == host) {
172 AclClassification::DeniedUserAcl
173 } else if self.allowed_hosts.iter().any(|h| h.as_ref() == host) {
174 AclClassification::AllowedUserAcl
175 } else if self.host_acl_default {
176 AclClassification::AllowedDefault
177 } else {
178 AclClassification::DeniedDefault
179 }
180 }
181
182 pub fn is_port_allowed(&self, port: u16) -> AclClassification {
184 if Self::is_port_in_ranges(port, &self.denied_port_ranges) {
185 AclClassification::DeniedUserAcl
186 } else if Self::is_port_in_ranges(port, &self.allowed_port_ranges) {
187 AclClassification::AllowedUserAcl
188 } else if self.port_acl_default {
189 AclClassification::AllowedDefault
190 } else {
191 AclClassification::DeniedDefault
192 }
193 }
194
195 pub fn is_ip_allowed(&self, ip: &IpAddr) -> AclClassification {
197 if (!utils::ip::is_global_ip(ip) || ip.is_loopback()) && !utils::ip::is_private_ip(ip) {
198 if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
199 return AclClassification::AllowedUserAcl;
200 } else {
201 return AclClassification::DeniedNotGlobal;
202 }
203 }
204
205 if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
206 AclClassification::AllowedUserAcl
207 } else if Self::is_ip_in_ranges(ip, &self.denied_ip_ranges) {
208 AclClassification::DeniedUserAcl
209 } else if utils::ip::is_private_ip(ip) && !self.allow_private_ip_ranges {
210 AclClassification::DeniedPrivateRange
211 } else if self.ip_acl_default {
212 AclClassification::AllowedDefault
213 } else {
214 AclClassification::DeniedDefault
215 }
216 }
217
218 pub fn resolve_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
220 self.static_dns_mapping.get(host).copied()
221 }
222
223 pub fn is_header_allowed(&self, header_name: &str, header_value: &str) -> AclClassification {
225 if let Some(allowed_value) = self.allowed_headers.get(header_name) {
226 if allowed_value.as_deref() == Some(header_value) || allowed_value.is_none() {
227 AclClassification::AllowedUserAcl
228 } else {
229 AclClassification::DeniedUserAcl
230 }
231 } else if let Some(denied_value) = self.denied_headers.get(header_name) {
232 if denied_value.as_deref() == Some(header_value) || denied_value.is_none() {
233 AclClassification::DeniedUserAcl
234 } else {
235 AclClassification::AllowedUserAcl
236 }
237 } else if self.header_acl_default {
238 AclClassification::AllowedDefault
239 } else {
240 AclClassification::DeniedDefault
241 }
242 }
243
244 pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
246 if self.allowed_url_paths_router.at(url_path).is_ok() {
247 AclClassification::AllowedUserAcl
248 } else if self.denied_url_paths_router.at(url_path).is_ok() {
249 AclClassification::DeniedUserAcl
250 } else if self.url_path_acl_default {
251 AclClassification::AllowedDefault
252 } else {
253 AclClassification::DeniedDefault
254 }
255 }
256
257 fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
259 ranges.iter().any(|range| range.contains(ip))
260 }
261
262 fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
264 ranges.iter().any(|range| range.contains(&port))
265 }
266}
267
268#[non_exhaustive]
270#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
271pub enum AclClassification {
272 AllowedUserAcl,
274 AllowedDefault,
276 DeniedUserAcl,
278 DeniedDefault,
280 Denied(String),
282 DeniedNotGlobal,
284 DeniedPrivateRange,
286}
287
288impl std::fmt::Display for AclClassification {
289 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
290 match self {
291 AclClassification::AllowedUserAcl => {
292 write!(f, "The entiy is allowed according to the allowed ACL.")
293 }
294 AclClassification::AllowedDefault => write!(
295 f,
296 "The entity is allowed because the default is to allow if no ACL match is found."
297 ),
298 AclClassification::DeniedUserAcl => {
299 write!(f, "The entiy is denied according to the denied ACL.")
300 }
301 AclClassification::DeniedNotGlobal => {
302 write!(f, "The ip is denied because it is not global.")
303 }
304 AclClassification::DeniedPrivateRange => {
305 write!(f, "The ip is denied because it is in a private range.")
306 }
307 AclClassification::DeniedDefault => write!(
308 f,
309 "The entity is denied because the default is to deny if no ACL match is found."
310 ),
311 AclClassification::Denied(reason) => {
312 write!(f, "The entiy is denied because {}.", reason)
313 }
314 }
315 }
316}
317
318impl AclClassification {
319 pub fn is_allowed(&self) -> bool {
321 matches!(
322 self,
323 AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
324 )
325 }
326
327 pub fn is_denied(&self) -> bool {
329 matches!(
330 self,
331 AclClassification::DeniedUserAcl
332 | AclClassification::Denied(_)
333 | AclClassification::DeniedDefault
334 | AclClassification::DeniedNotGlobal
335 | AclClassification::DeniedPrivateRange
336 )
337 }
338}
339
340#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
343pub enum HttpRequestMethod {
344 CONNECT,
346 DELETE,
348 GET,
350 HEAD,
352 OPTIONS,
354 PATCH,
356 POST,
358 PUT,
360 TRACE,
362 OTHER(Box<str>),
364}
365
366impl From<&str> for HttpRequestMethod {
367 fn from(method: &str) -> Self {
368 match method {
369 "CONNECT" => HttpRequestMethod::CONNECT,
370 "DELETE" => HttpRequestMethod::DELETE,
371 "GET" => HttpRequestMethod::GET,
372 "HEAD" => HttpRequestMethod::HEAD,
373 "OPTIONS" => HttpRequestMethod::OPTIONS,
374 "PATCH" => HttpRequestMethod::PATCH,
375 "POST" => HttpRequestMethod::POST,
376 "PUT" => HttpRequestMethod::PUT,
377 "TRACE" => HttpRequestMethod::TRACE,
378 _ => HttpRequestMethod::OTHER(method.into()),
379 }
380 }
381}
382
383impl HttpRequestMethod {
384 pub fn as_str(&self) -> &str {
386 match self {
387 HttpRequestMethod::CONNECT => "CONNECT",
388 HttpRequestMethod::DELETE => "DELETE",
389 HttpRequestMethod::GET => "GET",
390 HttpRequestMethod::HEAD => "HEAD",
391 HttpRequestMethod::OPTIONS => "OPTIONS",
392 HttpRequestMethod::PATCH => "PATCH",
393 HttpRequestMethod::POST => "POST",
394 HttpRequestMethod::PUT => "PUT",
395 HttpRequestMethod::TRACE => "TRACE",
396 HttpRequestMethod::OTHER(other) => other,
397 }
398 }
399}
400
401#[derive(Default, Clone)]
403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
404pub struct HttpAclBuilder {
405 allow_http: bool,
406 allow_https: bool,
407 allowed_methods: Vec<HttpRequestMethod>,
408 denied_methods: Vec<HttpRequestMethod>,
409 allowed_hosts: Vec<String>,
410 denied_hosts: Vec<String>,
411 allowed_port_ranges: Vec<RangeInclusive<u16>>,
412 denied_port_ranges: Vec<RangeInclusive<u16>>,
413 allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
414 denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
415 static_dns_mapping: HashMap<String, SocketAddr>,
416 allowed_headers: HashMap<String, Option<String>>,
417 denied_headers: HashMap<String, Option<String>>,
418 allowed_url_paths: Vec<String>,
419 #[cfg_attr(feature = "serde", serde(skip))]
420 allowed_url_paths_router: Router<()>,
421 denied_url_paths: Vec<String>,
422 #[cfg_attr(feature = "serde", serde(skip))]
423 denied_url_paths_router: Router<()>,
424 allow_private_ip_ranges: bool,
425 method_acl_default: bool,
426 host_acl_default: bool,
427 port_acl_default: bool,
428 ip_acl_default: bool,
429 header_acl_default: bool,
430 url_path_acl_default: bool,
431}
432
433impl std::fmt::Debug for HttpAclBuilder {
434 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
435 f.debug_struct("HttpAclBuilder")
436 .field("allow_http", &self.allow_http)
437 .field("allow_https", &self.allow_https)
438 .field("allowed_methods", &self.allowed_methods)
439 .field("denied_methods", &self.denied_methods)
440 .field("allowed_hosts", &self.allowed_hosts)
441 .field("denied_hosts", &self.denied_hosts)
442 .field("allowed_port_ranges", &self.allowed_port_ranges)
443 .field("denied_port_ranges", &self.denied_port_ranges)
444 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
445 .field("denied_ip_ranges", &self.denied_ip_ranges)
446 .field("static_dns_mapping", &self.static_dns_mapping)
447 .field("allowed_headers", &self.allowed_headers)
448 .field("denied_headers", &self.denied_headers)
449 .field("allowed_url_paths", &self.allowed_url_paths)
450 .field("denied_url_paths", &self.denied_url_paths)
451 .field("allow_private_ip_ranges", &self.allow_private_ip_ranges)
452 .field("method_acl_default", &self.method_acl_default)
453 .field("host_acl_default", &self.host_acl_default)
454 .field("port_acl_default", &self.port_acl_default)
455 .field("ip_acl_default", &self.ip_acl_default)
456 .field("header_acl_default", &self.header_acl_default)
457 .field("url_path_acl_default", &self.url_path_acl_default)
458 .finish()
459 }
460}
461
462impl PartialEq for HttpAclBuilder {
463 fn eq(&self, other: &Self) -> bool {
464 self.allow_http == other.allow_http
465 && self.allow_https == other.allow_https
466 && self.allowed_methods == other.allowed_methods
467 && self.denied_methods == other.denied_methods
468 && self.allowed_hosts == other.allowed_hosts
469 && self.denied_hosts == other.denied_hosts
470 && self.allowed_port_ranges == other.allowed_port_ranges
471 && self.denied_port_ranges == other.denied_port_ranges
472 && self.allowed_ip_ranges == other.allowed_ip_ranges
473 && self.denied_ip_ranges == other.denied_ip_ranges
474 && self.static_dns_mapping == other.static_dns_mapping
475 && self.allowed_headers == other.allowed_headers
476 && self.denied_headers == other.denied_headers
477 && self.allowed_url_paths == other.allowed_url_paths
478 && self.denied_url_paths == other.denied_url_paths
479 && self.allow_private_ip_ranges == other.allow_private_ip_ranges
480 && self.method_acl_default == other.method_acl_default
481 && self.host_acl_default == other.host_acl_default
482 && self.port_acl_default == other.port_acl_default
483 && self.ip_acl_default == other.ip_acl_default
484 && self.header_acl_default == other.header_acl_default
485 && self.url_path_acl_default == other.url_path_acl_default
486 }
487}
488
489impl HttpAclBuilder {
490 pub fn new() -> Self {
492 Self {
493 allow_http: true,
494 allow_https: true,
495 allowed_methods: vec![
496 HttpRequestMethod::CONNECT,
497 HttpRequestMethod::DELETE,
498 HttpRequestMethod::GET,
499 HttpRequestMethod::HEAD,
500 HttpRequestMethod::OPTIONS,
501 HttpRequestMethod::PATCH,
502 HttpRequestMethod::POST,
503 HttpRequestMethod::PUT,
504 HttpRequestMethod::TRACE,
505 ],
506 denied_methods: Vec::new(),
507 allowed_hosts: Vec::new(),
508 denied_hosts: Vec::new(),
509 allowed_port_ranges: vec![80..=80, 443..=443],
510 denied_port_ranges: Vec::new(),
511 allowed_ip_ranges: Vec::new(),
512 denied_ip_ranges: Vec::new(),
513 allowed_headers: HashMap::new(),
514 denied_headers: HashMap::new(),
515 allowed_url_paths: Vec::new(),
516 allowed_url_paths_router: Router::new(),
517 denied_url_paths: Vec::new(),
518 denied_url_paths_router: Router::new(),
519 allow_private_ip_ranges: false,
520 static_dns_mapping: HashMap::new(),
521 method_acl_default: false,
522 host_acl_default: false,
523 port_acl_default: false,
524 ip_acl_default: false,
525 header_acl_default: false,
526 url_path_acl_default: true,
527 }
528 }
529
530 pub fn http(mut self, allow: bool) -> Self {
532 self.allow_http = allow;
533 self
534 }
535
536 pub fn https(mut self, allow: bool) -> Self {
538 self.allow_https = allow;
539 self
540 }
541
542 pub fn private_ip_ranges(mut self, allow: bool) -> Self {
544 self.allow_private_ip_ranges = allow;
545 self
546 }
547
548 pub fn method_acl_default(mut self, allow: bool) -> Self {
550 self.method_acl_default = allow;
551 self
552 }
553
554 pub fn host_acl_default(mut self, allow: bool) -> Self {
556 self.host_acl_default = allow;
557 self
558 }
559
560 pub fn port_acl_default(mut self, allow: bool) -> Self {
562 self.port_acl_default = allow;
563 self
564 }
565
566 pub fn ip_acl_default(mut self, allow: bool) -> Self {
568 self.ip_acl_default = allow;
569 self
570 }
571
572 pub fn header_acl_default(mut self, allow: bool) -> Self {
574 self.header_acl_default = allow;
575 self
576 }
577
578 pub fn url_path_acl_default(mut self, allow: bool) -> Self {
580 self.url_path_acl_default = allow;
581 self
582 }
583
584 pub fn add_allowed_method(
586 mut self,
587 method: impl Into<HttpRequestMethod>,
588 ) -> Result<Self, AddError> {
589 let method = method.into();
590 if self.denied_methods.contains(&method) {
591 Err(AddError::AlreadyDenied)
592 } else if self.allowed_methods.contains(&method) {
593 Err(AddError::AlreadyAllowed)
594 } else {
595 self.allowed_methods.push(method);
596 Ok(self)
597 }
598 }
599
600 pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
602 let method = method.into();
603 self.allowed_methods.retain(|m| m != &method);
604 self
605 }
606
607 pub fn allowed_methods(
609 mut self,
610 methods: Vec<impl Into<HttpRequestMethod>>,
611 ) -> Result<Self, AddError> {
612 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
613
614 for method in &methods {
615 if self.denied_methods.contains(method) {
616 return Err(AddError::AlreadyDenied);
617 } else if self.allowed_methods.contains(method) {
618 return Err(AddError::AlreadyAllowed);
619 }
620 }
621 self.allowed_methods = methods;
622 Ok(self)
623 }
624
625 pub fn clear_allowed_methods(mut self) -> Self {
627 self.allowed_methods.clear();
628 self
629 }
630
631 pub fn add_denied_method(
633 mut self,
634 method: impl Into<HttpRequestMethod>,
635 ) -> Result<Self, AddError> {
636 let method = method.into();
637 if self.allowed_methods.contains(&method) {
638 Err(AddError::AlreadyAllowed)
639 } else if self.denied_methods.contains(&method) {
640 Err(AddError::AlreadyDenied)
641 } else {
642 self.denied_methods.push(method);
643 Ok(self)
644 }
645 }
646
647 pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
649 let method = method.into();
650 self.denied_methods.retain(|m| m != &method);
651 self
652 }
653
654 pub fn denied_methods(
656 mut self,
657 methods: Vec<impl Into<HttpRequestMethod>>,
658 ) -> Result<Self, AddError> {
659 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
660
661 for method in &methods {
662 if self.allowed_methods.contains(method) {
663 return Err(AddError::AlreadyAllowed);
664 } else if self.denied_methods.contains(method) {
665 return Err(AddError::AlreadyDenied);
666 }
667 }
668 self.denied_methods = methods;
669 Ok(self)
670 }
671
672 pub fn clear_denied_methods(mut self) -> Self {
674 self.denied_methods.clear();
675 self
676 }
677
678 pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
680 if utils::authority::is_valid_host(&host) {
681 if self.denied_hosts.contains(&host) {
682 Err(AddError::AlreadyDenied)
683 } else if self.allowed_hosts.contains(&host) {
684 Err(AddError::AlreadyAllowed)
685 } else {
686 self.allowed_hosts.push(host);
687 Ok(self)
688 }
689 } else {
690 Err(AddError::Invalid)
691 }
692 }
693
694 pub fn remove_allowed_host(mut self, host: String) -> Self {
696 self.allowed_hosts.retain(|h| h != &host);
697 self
698 }
699
700 pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
702 for host in &hosts {
703 if utils::authority::is_valid_host(host) {
704 if self.denied_hosts.contains(host) {
705 return Err(AddError::AlreadyDenied);
706 } else if self.allowed_hosts.contains(host) {
707 return Err(AddError::AlreadyAllowed);
708 }
709 } else {
710 return Err(AddError::Invalid);
711 }
712 }
713 self.allowed_hosts = hosts;
714 Ok(self)
715 }
716
717 pub fn clear_allowed_hosts(mut self) -> Self {
719 self.allowed_hosts.clear();
720 self
721 }
722
723 pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
725 if utils::authority::is_valid_host(&host) {
726 if self.allowed_hosts.contains(&host) {
727 Err(AddError::AlreadyAllowed)
728 } else if self.denied_hosts.contains(&host) {
729 Err(AddError::AlreadyDenied)
730 } else {
731 self.denied_hosts.push(host);
732 Ok(self)
733 }
734 } else {
735 Err(AddError::Invalid)
736 }
737 }
738
739 pub fn remove_denied_host(mut self, host: String) -> Self {
741 self.denied_hosts.retain(|h| h != &host);
742 self
743 }
744
745 pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
747 for host in &hosts {
748 if utils::authority::is_valid_host(host) {
749 if self.allowed_hosts.contains(host) {
750 return Err(AddError::AlreadyAllowed);
751 } else if self.denied_hosts.contains(host) {
752 return Err(AddError::AlreadyDenied);
753 }
754 } else {
755 return Err(AddError::Invalid);
756 }
757 }
758 self.denied_hosts = hosts;
759 Ok(self)
760 }
761
762 pub fn clear_denied_hosts(mut self) -> Self {
764 self.denied_hosts.clear();
765 self
766 }
767
768 pub fn add_allowed_port_range(
770 mut self,
771 port_range: RangeInclusive<u16>,
772 ) -> Result<Self, AddError> {
773 if self.denied_port_ranges.contains(&port_range) {
774 Err(AddError::AlreadyDenied)
775 } else if self.allowed_port_ranges.contains(&port_range) {
776 Err(AddError::AlreadyAllowed)
777 } else {
778 self.allowed_port_ranges.push(port_range);
779 Ok(self)
780 }
781 }
782
783 pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
785 self.allowed_port_ranges.retain(|p| p != &port_range);
786 self
787 }
788
789 pub fn allowed_port_ranges(
791 mut self,
792 port_ranges: Vec<RangeInclusive<u16>>,
793 ) -> Result<Self, AddError> {
794 for port_range in &port_ranges {
795 if self.denied_port_ranges.contains(port_range) {
796 return Err(AddError::AlreadyDenied);
797 } else if self.allowed_port_ranges.contains(port_range) {
798 return Err(AddError::AlreadyAllowed);
799 }
800 }
801 self.allowed_port_ranges = port_ranges;
802 Ok(self)
803 }
804
805 pub fn clear_allowed_port_ranges(mut self) -> Self {
807 self.allowed_port_ranges.clear();
808 self
809 }
810
811 pub fn add_denied_port_range(
813 mut self,
814 port_range: RangeInclusive<u16>,
815 ) -> Result<Self, AddError> {
816 if self.allowed_port_ranges.contains(&port_range) {
817 Err(AddError::AlreadyAllowed)
818 } else if self.denied_port_ranges.contains(&port_range) {
819 Err(AddError::AlreadyDenied)
820 } else {
821 self.denied_port_ranges.push(port_range);
822 Ok(self)
823 }
824 }
825
826 pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
828 self.denied_port_ranges.retain(|p| p != &port_range);
829 self
830 }
831
832 pub fn denied_port_ranges(
834 mut self,
835 port_ranges: Vec<RangeInclusive<u16>>,
836 ) -> Result<Self, AddError> {
837 for port_range in &port_ranges {
838 if self.allowed_port_ranges.contains(port_range) {
839 return Err(AddError::AlreadyAllowed);
840 } else if self.denied_port_ranges.contains(port_range) {
841 return Err(AddError::AlreadyDenied);
842 }
843 }
844 self.denied_port_ranges = port_ranges;
845 Ok(self)
846 }
847
848 pub fn clear_denied_port_ranges(mut self) -> Self {
850 self.denied_port_ranges.clear();
851 self
852 }
853
854 pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
856 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
857 if self.denied_ip_ranges.contains(&ip_range) {
858 return Err(AddError::AlreadyDenied);
859 } else if self.allowed_ip_ranges.contains(&ip_range) {
860 return Err(AddError::AlreadyAllowed);
861 }
862 self.allowed_ip_ranges.push(ip_range);
863 Ok(self)
864 }
865
866 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
868 mut self,
869 ip_range: Ip,
870 ) -> Result<Self, AddError> {
871 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
872 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
873 Ok(self)
874 }
875
876 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
878 mut self,
879 ip_ranges: Vec<Ip>,
880 ) -> Result<Self, AddError> {
881 let ip_ranges = ip_ranges
882 .into_iter()
883 .map(|ip| ip.into_range())
884 .collect::<Option<Vec<_>>>()
885 .ok_or(AddError::Invalid)?;
886 for ip_range in &ip_ranges {
887 if self.denied_ip_ranges.contains(ip_range) {
888 return Err(AddError::AlreadyDenied);
889 } else if self.allowed_ip_ranges.contains(ip_range) {
890 return Err(AddError::AlreadyAllowed);
891 }
892 }
893 self.allowed_ip_ranges = ip_ranges;
894 Ok(self)
895 }
896
897 pub fn clear_allowed_ip_ranges(mut self) -> Self {
899 self.allowed_ip_ranges.clear();
900 self
901 }
902
903 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
905 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
906 if self.allowed_ip_ranges.contains(&ip_range) {
907 return Err(AddError::AlreadyAllowed);
908 } else if self.denied_ip_ranges.contains(&ip_range) {
909 return Err(AddError::AlreadyDenied);
910 }
911 self.denied_ip_ranges.push(ip_range);
912 Ok(self)
913 }
914
915 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
917 mut self,
918 ip_range: Ip,
919 ) -> Result<Self, AddError> {
920 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
921 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
922 Ok(self)
923 }
924
925 pub fn denied_ip_ranges<Ip: IntoIpRange>(
927 mut self,
928 ip_ranges: Vec<Ip>,
929 ) -> Result<Self, AddError> {
930 let ip_ranges = ip_ranges
931 .into_iter()
932 .map(|ip| ip.into_range())
933 .collect::<Option<Vec<_>>>()
934 .ok_or(AddError::Invalid)?;
935 for ip_range in &ip_ranges {
936 if self.allowed_ip_ranges.contains(ip_range) {
937 return Err(AddError::AlreadyAllowed);
938 } else if self.denied_ip_ranges.contains(ip_range) {
939 return Err(AddError::AlreadyDenied);
940 }
941 }
942 self.denied_ip_ranges = ip_ranges;
943 Ok(self)
944 }
945
946 pub fn clear_denied_ip_ranges(mut self) -> Self {
948 self.denied_ip_ranges.clear();
949 self
950 }
951
952 pub fn add_static_dns_mapping(
954 mut self,
955 host: String,
956 sock_addr: SocketAddr,
957 ) -> Result<Self, AddError> {
958 if utils::authority::is_valid_host(&host) {
959 self.static_dns_mapping.insert(host, sock_addr);
960 Ok(self)
961 } else {
962 Err(AddError::Invalid)
963 }
964 }
965
966 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
968 self.static_dns_mapping.remove(host);
969 self
970 }
971
972 pub fn static_dns_mappings(
974 mut self,
975 mappings: HashMap<String, SocketAddr>,
976 ) -> Result<Self, AddError> {
977 for (host, ip) in &mappings {
978 if utils::authority::is_valid_host(host) {
979 self.static_dns_mapping.insert(host.to_string(), *ip);
980 } else {
981 return Err(AddError::Invalid);
982 }
983 }
984 Ok(self)
985 }
986
987 pub fn clear_static_dns_mappings(mut self) -> Self {
989 self.static_dns_mapping.clear();
990 self
991 }
992
993 pub fn add_allowed_header(
995 mut self,
996 header: String,
997 value: Option<String>,
998 ) -> Result<Self, AddError> {
999 if self.denied_headers.contains_key(&header) {
1000 Err(AddError::AlreadyDenied)
1001 } else if let std::collections::hash_map::Entry::Vacant(e) =
1002 self.allowed_headers.entry(header)
1003 {
1004 e.insert(value);
1005 Ok(self)
1006 } else {
1007 Err(AddError::AlreadyAllowed)
1008 }
1009 }
1010
1011 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1013 self.allowed_headers.remove(header);
1014 self
1015 }
1016
1017 pub fn allowed_headers(
1019 mut self,
1020 headers: HashMap<String, Option<String>>,
1021 ) -> Result<Self, AddError> {
1022 for header in headers.keys() {
1023 if self.denied_headers.contains_key(header) {
1024 return Err(AddError::AlreadyDenied);
1025 } else if self.allowed_headers.contains_key(header) {
1026 return Err(AddError::AlreadyAllowed);
1027 }
1028 }
1029 self.allowed_headers = headers;
1030 Ok(self)
1031 }
1032
1033 pub fn clear_allowed_headers(mut self) -> Self {
1035 self.allowed_headers.clear();
1036 self
1037 }
1038
1039 pub fn add_denied_header(
1041 mut self,
1042 header: String,
1043 value: Option<String>,
1044 ) -> Result<Self, AddError> {
1045 if self.allowed_headers.contains_key(&header) {
1046 Err(AddError::AlreadyAllowed)
1047 } else if let std::collections::hash_map::Entry::Vacant(e) =
1048 self.denied_headers.entry(header)
1049 {
1050 e.insert(value);
1051 Ok(self)
1052 } else {
1053 Err(AddError::AlreadyDenied)
1054 }
1055 }
1056
1057 pub fn remove_denied_header(mut self, header: &str) -> Self {
1059 self.denied_headers.remove(header);
1060 self
1061 }
1062
1063 pub fn denied_headers(
1065 mut self,
1066 headers: HashMap<String, Option<String>>,
1067 ) -> Result<Self, AddError> {
1068 for header in headers.keys() {
1069 if self.allowed_headers.contains_key(header) {
1070 return Err(AddError::AlreadyAllowed);
1071 } else if self.denied_headers.contains_key(header) {
1072 return Err(AddError::AlreadyDenied);
1073 }
1074 }
1075 self.denied_headers = headers;
1076 Ok(self)
1077 }
1078
1079 pub fn clear_denied_headers(mut self) -> Self {
1081 self.denied_headers.clear();
1082 self
1083 }
1084
1085 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1087 if self.denied_url_paths.contains(&url_path)
1088 || self.denied_url_paths_router.at(&url_path).is_ok()
1089 {
1090 Err(AddError::AlreadyDenied)
1091 } else if self.allowed_url_paths.contains(&url_path)
1092 || self.allowed_url_paths_router.at(&url_path).is_ok()
1093 {
1094 Err(AddError::AlreadyAllowed)
1095 } else {
1096 self.allowed_url_paths.push(url_path.clone());
1097 self.allowed_url_paths_router
1098 .insert(url_path, ())
1099 .map_err(|_| AddError::Invalid)?;
1100 Ok(self)
1101 }
1102 }
1103
1104 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1106 self.allowed_url_paths.retain(|p| p != url_path);
1107 self.allowed_url_paths_router = {
1108 let mut router = Router::new();
1109 for url_path in &self.allowed_url_paths {
1110 router
1111 .insert(url_path.clone(), ())
1112 .expect("failed to insert url path");
1113 }
1114 router
1115 };
1116 self
1117 }
1118
1119 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1121 for url_path in &url_paths {
1122 if self.denied_url_paths.contains(url_path)
1123 || self.denied_url_paths_router.at(url_path).is_ok()
1124 {
1125 return Err(AddError::AlreadyDenied);
1126 } else if self.allowed_url_paths.contains(url_path)
1127 || self.allowed_url_paths_router.at(url_path).is_ok()
1128 {
1129 return Err(AddError::AlreadyAllowed);
1130 }
1131 }
1132 for url_path in &url_paths {
1133 self.allowed_url_paths_router
1134 .insert(url_path.clone(), ())
1135 .map_err(|_| AddError::Invalid)?;
1136 }
1137 self.allowed_url_paths = url_paths;
1138 Ok(self)
1139 }
1140
1141 pub fn clear_allowed_url_paths(mut self) -> Self {
1143 self.allowed_url_paths.clear();
1144 self.allowed_url_paths_router = Router::new();
1145 self
1146 }
1147
1148 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1150 if self.allowed_url_paths.contains(&url_path)
1151 || self.allowed_url_paths_router.at(&url_path).is_ok()
1152 {
1153 Err(AddError::AlreadyAllowed)
1154 } else if self.denied_url_paths.contains(&url_path)
1155 || self.denied_url_paths_router.at(&url_path).is_ok()
1156 {
1157 Err(AddError::AlreadyDenied)
1158 } else {
1159 self.denied_url_paths.push(url_path.clone());
1160 self.denied_url_paths_router
1161 .insert(url_path, ())
1162 .map_err(|_| AddError::Invalid)?;
1163 Ok(self)
1164 }
1165 }
1166
1167 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1169 self.denied_url_paths.retain(|p| p != url_path);
1170 self.denied_url_paths_router = {
1171 let mut router = Router::new();
1172 for url_path in &self.denied_url_paths {
1173 router
1174 .insert(url_path.clone(), ())
1175 .expect("failed to insert url path");
1176 }
1177 router
1178 };
1179 self
1180 }
1181
1182 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1184 for url_path in &url_paths {
1185 if self.allowed_url_paths.contains(url_path)
1186 || self.allowed_url_paths_router.at(url_path).is_ok()
1187 {
1188 return Err(AddError::AlreadyAllowed);
1189 } else if self.denied_url_paths.contains(url_path)
1190 || self.denied_url_paths_router.at(url_path).is_ok()
1191 {
1192 return Err(AddError::AlreadyDenied);
1193 }
1194 }
1195 for url_path in &url_paths {
1196 self.denied_url_paths_router
1197 .insert(url_path.clone(), ())
1198 .map_err(|_| AddError::Invalid)?;
1199 }
1200 self.denied_url_paths = url_paths;
1201 Ok(self)
1202 }
1203
1204 pub fn clear_denied_url_paths(mut self) -> Self {
1206 self.denied_url_paths.clear();
1207 self.denied_url_paths_router = Router::new();
1208 self
1209 }
1210
1211 pub fn build(self) -> HttpAcl {
1213 HttpAcl {
1214 allow_http: self.allow_http,
1215 allow_https: self.allow_https,
1216 allowed_methods: self.allowed_methods.into_boxed_slice(),
1217 denied_methods: self.denied_methods.into_boxed_slice(),
1218 allowed_hosts: self
1219 .allowed_hosts
1220 .into_iter()
1221 .map(|x| x.into_boxed_str())
1222 .collect(),
1223 denied_hosts: self
1224 .denied_hosts
1225 .into_iter()
1226 .map(|x| x.into_boxed_str())
1227 .collect(),
1228 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1229 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1230 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1231 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1232 allowed_headers: self
1233 .allowed_headers
1234 .into_iter()
1235 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1236 .collect(),
1237 denied_headers: self
1238 .denied_headers
1239 .into_iter()
1240 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1241 .collect(),
1242 allowed_url_paths_router: self.allowed_url_paths_router,
1243 denied_url_paths_router: self.denied_url_paths_router,
1244 static_dns_mapping: self
1245 .static_dns_mapping
1246 .into_iter()
1247 .map(|(k, v)| (k.into_boxed_str(), v))
1248 .collect(),
1249 allow_private_ip_ranges: self.allow_private_ip_ranges,
1250 method_acl_default: self.method_acl_default,
1251 host_acl_default: self.host_acl_default,
1252 port_acl_default: self.port_acl_default,
1253 ip_acl_default: self.ip_acl_default,
1254 header_acl_default: self.header_acl_default,
1255 url_path_acl_default: self.url_path_acl_default,
1256 }
1257 }
1258
1259 pub fn try_build(mut self) -> Result<HttpAcl, AddError> {
1262 if !utils::has_unique_elements(&self.allowed_methods) {
1263 return Err(AddError::AlreadyAllowed);
1264 }
1265 for method in &self.allowed_methods {
1266 if self.denied_methods.contains(method) {
1267 return Err(AddError::AlreadyDenied);
1268 }
1269 }
1270 if !utils::has_unique_elements(&self.denied_methods) {
1271 return Err(AddError::AlreadyDenied);
1272 }
1273 for method in &self.denied_methods {
1274 if self.allowed_methods.contains(method) {
1275 return Err(AddError::AlreadyAllowed);
1276 }
1277 }
1278 if !utils::has_unique_elements(&self.allowed_hosts) {
1279 return Err(AddError::AlreadyAllowed);
1280 }
1281 for host in &self.allowed_hosts {
1282 if utils::authority::is_valid_host(host) {
1283 return Err(AddError::Invalid);
1284 }
1285 if self.denied_hosts.contains(host) {
1286 return Err(AddError::AlreadyDenied);
1287 }
1288 }
1289 if !utils::has_unique_elements(&self.denied_hosts) {
1290 return Err(AddError::AlreadyDenied);
1291 }
1292 for host in &self.denied_hosts {
1293 if utils::authority::is_valid_host(host) {
1294 return Err(AddError::Invalid);
1295 }
1296 if self.allowed_hosts.contains(host) {
1297 return Err(AddError::AlreadyAllowed);
1298 }
1299 }
1300 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1301 return Err(AddError::AlreadyAllowed);
1302 }
1303 for port_range in &self.allowed_port_ranges {
1304 if self.denied_port_ranges.contains(port_range) {
1305 return Err(AddError::AlreadyDenied);
1306 }
1307 }
1308 if !utils::has_unique_elements(&self.denied_port_ranges) {
1309 return Err(AddError::AlreadyDenied);
1310 }
1311 for port_range in &self.denied_port_ranges {
1312 if self.allowed_port_ranges.contains(port_range) {
1313 return Err(AddError::AlreadyAllowed);
1314 }
1315 }
1316 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1317 return Err(AddError::AlreadyAllowed);
1318 }
1319 for ip_range in &self.allowed_ip_ranges {
1320 if self.denied_ip_ranges.contains(ip_range) {
1321 return Err(AddError::AlreadyDenied);
1322 }
1323 }
1324 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1325 return Err(AddError::AlreadyDenied);
1326 }
1327 for ip_range in &self.denied_ip_ranges {
1328 if self.allowed_ip_ranges.contains(ip_range) {
1329 return Err(AddError::AlreadyAllowed);
1330 }
1331 }
1332 if !utils::has_unique_elements(&self.static_dns_mapping) {
1333 return Err(AddError::AlreadyAllowed);
1334 }
1335 for host in self.static_dns_mapping.keys() {
1336 if !utils::authority::is_valid_host(host) {
1337 return Err(AddError::Invalid);
1338 }
1339 }
1340 if !utils::has_unique_elements(&self.allowed_url_paths) {
1341 return Err(AddError::AlreadyAllowed);
1342 }
1343 for url_path in &self.allowed_url_paths {
1344 if self.denied_url_paths.contains(url_path)
1345 || self.denied_url_paths_router.at(url_path).is_ok()
1346 {
1347 return Err(AddError::AlreadyDenied);
1348 } else if self.allowed_url_paths_router.at(url_path).is_ok() {
1349 return Err(AddError::AlreadyAllowed);
1350 } else {
1351 self.allowed_url_paths_router
1352 .insert(url_path.clone(), ())
1353 .map_err(|_| AddError::Invalid)?;
1354 }
1355 }
1356 if !utils::has_unique_elements(&self.denied_url_paths) {
1357 return Err(AddError::AlreadyDenied);
1358 }
1359 for url_path in &self.denied_url_paths {
1360 if self.allowed_url_paths.contains(url_path)
1361 || self.allowed_url_paths_router.at(url_path).is_ok()
1362 {
1363 return Err(AddError::AlreadyAllowed);
1364 } else if self.denied_url_paths_router.at(url_path).is_ok() {
1365 return Err(AddError::AlreadyDenied);
1366 } else {
1367 self.denied_url_paths_router
1368 .insert(url_path.clone(), ())
1369 .map_err(|_| AddError::Invalid)?;
1370 }
1371 }
1372 Ok(self.build())
1373 }
1374}