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: false,
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: false,
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::AlreadyDenied)
623 } else if self.allowed_methods.contains(&method) {
624 Err(AddError::AlreadyAllowed)
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::AlreadyDenied);
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::AlreadyAllowed)
668 } else if self.denied_methods.contains(&method) {
669 Err(AddError::AlreadyDenied)
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::AlreadyAllowed);
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::AlreadyDenied)
710 } else if self.allowed_hosts.contains(&host) {
711 Err(AddError::AlreadyAllowed)
712 } else {
713 self.allowed_hosts.push(host);
714 Ok(self)
715 }
716 } else {
717 Err(AddError::Invalid)
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::AlreadyDenied);
733 }
734 } else {
735 return Err(AddError::Invalid);
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::AlreadyAllowed)
753 } else if self.denied_hosts.contains(&host) {
754 Err(AddError::AlreadyDenied)
755 } else {
756 self.denied_hosts.push(host);
757 Ok(self)
758 }
759 } else {
760 Err(AddError::Invalid)
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::AlreadyAllowed);
776 }
777 } else {
778 return Err(AddError::Invalid);
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::AlreadyDenied)
798 } else if self.allowed_port_ranges.contains(&port_range) {
799 Err(AddError::AlreadyAllowed)
800 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range)
801 || utils::range_overlaps(&self.denied_port_ranges, &port_range)
802 {
803 Err(AddError::Invalid)
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 port_range in &port_ranges {
822 if self.denied_port_ranges.contains(port_range) {
823 return Err(AddError::AlreadyDenied);
824 } else if utils::range_overlaps(&port_ranges, port_range)
825 || utils::range_overlaps(&self.denied_port_ranges, port_range)
826 {
827 return Err(AddError::Invalid);
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::AlreadyAllowed)
847 } else if self.denied_port_ranges.contains(&port_range) {
848 Err(AddError::AlreadyDenied)
849 } else if utils::range_overlaps(&self.allowed_port_ranges, &port_range)
850 || utils::range_overlaps(&self.denied_port_ranges, &port_range)
851 {
852 Err(AddError::Invalid)
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::AlreadyAllowed);
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.into_range().ok_or(AddError::Invalid)?;
888 if self.denied_ip_ranges.contains(&ip_range) {
889 return Err(AddError::AlreadyDenied);
890 } else if self.allowed_ip_ranges.contains(&ip_range) {
891 return Err(AddError::AlreadyAllowed);
892 } else if utils::range_overlaps(&self.allowed_ip_ranges, &ip_range)
893 || utils::range_overlaps(&self.denied_ip_ranges, &ip_range)
894 {
895 return Err(AddError::Invalid);
896 }
897 self.allowed_ip_ranges.push(ip_range);
898 Ok(self)
899 }
900
901 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
903 mut self,
904 ip_range: Ip,
905 ) -> Result<Self, AddError> {
906 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
907 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
908 Ok(self)
909 }
910
911 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
913 mut self,
914 ip_ranges: Vec<Ip>,
915 ) -> Result<Self, AddError> {
916 let ip_ranges = ip_ranges
917 .into_iter()
918 .map(|ip| ip.into_range())
919 .collect::<Option<Vec<_>>>()
920 .ok_or(AddError::Invalid)?;
921 for ip_range in &ip_ranges {
922 if self.denied_ip_ranges.contains(ip_range) {
923 return Err(AddError::AlreadyDenied);
924 } else if utils::range_overlaps(&ip_ranges, ip_range)
925 || utils::range_overlaps(&self.denied_ip_ranges, ip_range)
926 {
927 return Err(AddError::Invalid);
928 }
929 }
930 self.allowed_ip_ranges = ip_ranges;
931 Ok(self)
932 }
933
934 pub fn clear_allowed_ip_ranges(mut self) -> Self {
936 self.allowed_ip_ranges.clear();
937 self
938 }
939
940 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
942 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
943 if self.allowed_ip_ranges.contains(&ip_range) {
944 return Err(AddError::AlreadyAllowed);
945 } else if self.denied_ip_ranges.contains(&ip_range) {
946 return Err(AddError::AlreadyDenied);
947 }
948 self.denied_ip_ranges.push(ip_range);
949 Ok(self)
950 }
951
952 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
954 mut self,
955 ip_range: Ip,
956 ) -> Result<Self, AddError> {
957 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
958 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
959 Ok(self)
960 }
961
962 pub fn denied_ip_ranges<Ip: IntoIpRange>(
964 mut self,
965 ip_ranges: Vec<Ip>,
966 ) -> Result<Self, AddError> {
967 let ip_ranges = ip_ranges
968 .into_iter()
969 .map(|ip| ip.into_range())
970 .collect::<Option<Vec<_>>>()
971 .ok_or(AddError::Invalid)?;
972 for ip_range in &ip_ranges {
973 if self.allowed_ip_ranges.contains(ip_range) {
974 return Err(AddError::AlreadyAllowed);
975 } else if utils::range_overlaps(&self.allowed_ip_ranges, ip_range)
976 || utils::range_overlaps(&ip_ranges, ip_range)
977 {
978 return Err(AddError::Invalid);
979 }
980 }
981 self.denied_ip_ranges = ip_ranges;
982 Ok(self)
983 }
984
985 pub fn clear_denied_ip_ranges(mut self) -> Self {
987 self.denied_ip_ranges.clear();
988 self
989 }
990
991 pub fn add_static_dns_mapping(
993 mut self,
994 host: String,
995 sock_addr: SocketAddr,
996 ) -> Result<Self, AddError> {
997 if utils::authority::is_valid_host(&host) {
998 self.static_dns_mapping.insert(host, sock_addr);
999 Ok(self)
1000 } else {
1001 Err(AddError::Invalid)
1002 }
1003 }
1004
1005 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
1007 self.static_dns_mapping.remove(host);
1008 self
1009 }
1010
1011 pub fn static_dns_mappings(
1013 mut self,
1014 mappings: HashMap<String, SocketAddr>,
1015 ) -> Result<Self, AddError> {
1016 for (host, ip) in &mappings {
1017 if utils::authority::is_valid_host(host) {
1018 self.static_dns_mapping.insert(host.to_string(), *ip);
1019 } else {
1020 return Err(AddError::Invalid);
1021 }
1022 }
1023 Ok(self)
1024 }
1025
1026 pub fn clear_static_dns_mappings(mut self) -> Self {
1028 self.static_dns_mapping.clear();
1029 self
1030 }
1031
1032 pub fn add_allowed_header(
1034 mut self,
1035 header: String,
1036 value: Option<String>,
1037 ) -> Result<Self, AddError> {
1038 if self.denied_headers.contains_key(&header) {
1039 Err(AddError::AlreadyDenied)
1040 } else if let Entry::Vacant(e) = self.allowed_headers.entry(header) {
1041 e.insert(value);
1042 Ok(self)
1043 } else {
1044 Err(AddError::AlreadyAllowed)
1045 }
1046 }
1047
1048 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1050 self.allowed_headers.remove(header);
1051 self
1052 }
1053
1054 pub fn allowed_headers(
1056 mut self,
1057 headers: HashMap<String, Option<String>>,
1058 ) -> Result<Self, AddError> {
1059 for header in headers.keys() {
1060 if self.denied_headers.contains_key(header) {
1061 return Err(AddError::AlreadyDenied);
1062 }
1063 }
1064 self.allowed_headers = headers;
1065 Ok(self)
1066 }
1067
1068 pub fn clear_allowed_headers(mut self) -> Self {
1070 self.allowed_headers.clear();
1071 self
1072 }
1073
1074 pub fn add_denied_header(
1076 mut self,
1077 header: String,
1078 value: Option<String>,
1079 ) -> Result<Self, AddError> {
1080 if self.allowed_headers.contains_key(&header) {
1081 Err(AddError::AlreadyAllowed)
1082 } else if let Entry::Vacant(e) = self.denied_headers.entry(header) {
1083 e.insert(value);
1084 Ok(self)
1085 } else {
1086 Err(AddError::AlreadyDenied)
1087 }
1088 }
1089
1090 pub fn remove_denied_header(mut self, header: &str) -> Self {
1092 self.denied_headers.remove(header);
1093 self
1094 }
1095
1096 pub fn denied_headers(
1098 mut self,
1099 headers: HashMap<String, Option<String>>,
1100 ) -> Result<Self, AddError> {
1101 for header in headers.keys() {
1102 if self.allowed_headers.contains_key(header) {
1103 return Err(AddError::AlreadyAllowed);
1104 }
1105 }
1106 self.denied_headers = headers;
1107 Ok(self)
1108 }
1109
1110 pub fn clear_denied_headers(mut self) -> Self {
1112 self.denied_headers.clear();
1113 self
1114 }
1115
1116 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1118 if self.denied_url_paths.contains(&url_path)
1119 || self.denied_url_paths_router.at(&url_path).is_ok()
1120 {
1121 Err(AddError::AlreadyDenied)
1122 } else if self.allowed_url_paths.contains(&url_path)
1123 || self.allowed_url_paths_router.at(&url_path).is_ok()
1124 {
1125 Err(AddError::AlreadyAllowed)
1126 } else {
1127 self.allowed_url_paths.push(url_path.clone());
1128 self.allowed_url_paths_router
1129 .insert(url_path, ())
1130 .map_err(|_| AddError::Invalid)?;
1131 Ok(self)
1132 }
1133 }
1134
1135 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1137 self.allowed_url_paths.retain(|p| p != url_path);
1138 self.allowed_url_paths_router = {
1139 let mut router = Router::new();
1140 for url_path in &self.allowed_url_paths {
1141 router
1142 .insert(url_path.clone(), ())
1143 .expect("failed to insert url path");
1144 }
1145 router
1146 };
1147 self
1148 }
1149
1150 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1152 for url_path in &url_paths {
1153 if self.denied_url_paths.contains(url_path)
1154 || self.denied_url_paths_router.at(url_path).is_ok()
1155 {
1156 return Err(AddError::AlreadyDenied);
1157 }
1158 }
1159 self.allowed_url_paths_router = Router::new();
1160 for url_path in &url_paths {
1161 self.allowed_url_paths_router
1162 .insert(url_path.clone(), ())
1163 .map_err(|_| AddError::Invalid)?;
1164 }
1165 self.allowed_url_paths = url_paths;
1166 Ok(self)
1167 }
1168
1169 pub fn clear_allowed_url_paths(mut self) -> Self {
1171 self.allowed_url_paths.clear();
1172 self.allowed_url_paths_router = Router::new();
1173 self
1174 }
1175
1176 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1178 if self.allowed_url_paths.contains(&url_path)
1179 || self.allowed_url_paths_router.at(&url_path).is_ok()
1180 {
1181 Err(AddError::AlreadyAllowed)
1182 } else if self.denied_url_paths.contains(&url_path)
1183 || self.denied_url_paths_router.at(&url_path).is_ok()
1184 {
1185 Err(AddError::AlreadyDenied)
1186 } else {
1187 self.denied_url_paths.push(url_path.clone());
1188 self.denied_url_paths_router
1189 .insert(url_path, ())
1190 .map_err(|_| AddError::Invalid)?;
1191 Ok(self)
1192 }
1193 }
1194
1195 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1197 self.denied_url_paths.retain(|p| p != url_path);
1198 self.denied_url_paths_router = {
1199 let mut router = Router::new();
1200 for url_path in &self.denied_url_paths {
1201 router
1202 .insert(url_path.clone(), ())
1203 .expect("failed to insert url path");
1204 }
1205 router
1206 };
1207 self
1208 }
1209
1210 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1212 for url_path in &url_paths {
1213 if self.allowed_url_paths.contains(url_path)
1214 || self.allowed_url_paths_router.at(url_path).is_ok()
1215 {
1216 return Err(AddError::AlreadyAllowed);
1217 }
1218 }
1219 self.denied_url_paths_router = Router::new();
1220 for url_path in &url_paths {
1221 self.denied_url_paths_router
1222 .insert(url_path.clone(), ())
1223 .map_err(|_| AddError::Invalid)?;
1224 }
1225 self.denied_url_paths = url_paths;
1226 Ok(self)
1227 }
1228
1229 pub fn clear_denied_url_paths(mut self) -> Self {
1231 self.denied_url_paths.clear();
1232 self.denied_url_paths_router = Router::new();
1233 self
1234 }
1235
1236 pub fn build(self) -> HttpAcl {
1238 self.build_full(None)
1239 }
1240
1241 pub fn build_full(self, validate_fn: Option<ValidateFn>) -> HttpAcl {
1243 HttpAcl {
1244 allow_http: self.allow_http,
1245 allow_https: self.allow_https,
1246 allowed_methods: self.allowed_methods.into_iter().collect(),
1247 denied_methods: self.denied_methods.into_iter().collect(),
1248 allowed_hosts: self
1249 .allowed_hosts
1250 .into_iter()
1251 .map(|x| x.into_boxed_str())
1252 .collect(),
1253 denied_hosts: self
1254 .denied_hosts
1255 .into_iter()
1256 .map(|x| x.into_boxed_str())
1257 .collect(),
1258 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1259 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1260 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1261 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1262 allowed_headers: self
1263 .allowed_headers
1264 .into_iter()
1265 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1266 .collect(),
1267 denied_headers: self
1268 .denied_headers
1269 .into_iter()
1270 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1271 .collect(),
1272 allowed_url_paths_router: self.allowed_url_paths_router,
1273 denied_url_paths_router: self.denied_url_paths_router,
1274 static_dns_mapping: self
1275 .static_dns_mapping
1276 .into_iter()
1277 .map(|(k, v)| (k.into_boxed_str(), v))
1278 .collect(),
1279 validate_fn,
1280 allow_private_ip_ranges: self.allow_private_ip_ranges,
1281 method_acl_default: self.method_acl_default,
1282 host_acl_default: self.host_acl_default,
1283 port_acl_default: self.port_acl_default,
1284 ip_acl_default: self.ip_acl_default,
1285 header_acl_default: self.header_acl_default,
1286 url_path_acl_default: self.url_path_acl_default,
1287 }
1288 }
1289
1290 pub fn try_build(mut self) -> Result<HttpAcl, AddError> {
1293 if !utils::has_unique_elements(&self.allowed_methods) {
1294 return Err(AddError::AlreadyAllowed);
1295 }
1296 for method in &self.allowed_methods {
1297 if self.denied_methods.contains(method) {
1298 return Err(AddError::AlreadyDenied);
1299 }
1300 }
1301 if !utils::has_unique_elements(&self.denied_methods) {
1302 return Err(AddError::AlreadyDenied);
1303 }
1304 for method in &self.denied_methods {
1305 if self.allowed_methods.contains(method) {
1306 return Err(AddError::AlreadyAllowed);
1307 }
1308 }
1309 if !utils::has_unique_elements(&self.allowed_hosts) {
1310 return Err(AddError::AlreadyAllowed);
1311 }
1312 for host in &self.allowed_hosts {
1313 if !utils::authority::is_valid_host(host) {
1314 return Err(AddError::Invalid);
1315 }
1316 if self.denied_hosts.contains(host) {
1317 return Err(AddError::AlreadyDenied);
1318 }
1319 }
1320 if !utils::has_unique_elements(&self.denied_hosts) {
1321 return Err(AddError::AlreadyDenied);
1322 }
1323 for host in &self.denied_hosts {
1324 if !utils::authority::is_valid_host(host) {
1325 return Err(AddError::Invalid);
1326 }
1327 if self.allowed_hosts.contains(host) {
1328 return Err(AddError::AlreadyAllowed);
1329 }
1330 }
1331 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1332 return Err(AddError::AlreadyAllowed);
1333 }
1334 if utils::has_overlapping_ranges(&self.allowed_port_ranges) {
1336 return Err(AddError::Invalid);
1337 }
1338 for port_range in &self.allowed_port_ranges {
1339 if self.denied_port_ranges.contains(port_range) {
1340 return Err(AddError::AlreadyDenied);
1341 }
1342 }
1343 if !utils::has_unique_elements(&self.denied_port_ranges) {
1344 return Err(AddError::AlreadyDenied);
1345 }
1346 if utils::has_overlapping_ranges(&self.denied_port_ranges) {
1348 return Err(AddError::Invalid);
1349 }
1350 for port_range in &self.denied_port_ranges {
1351 if self.allowed_port_ranges.contains(port_range) {
1352 return Err(AddError::AlreadyAllowed);
1353 }
1354 }
1355 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1356 return Err(AddError::AlreadyAllowed);
1357 }
1358 if utils::has_overlapping_ranges(&self.allowed_ip_ranges) {
1360 return Err(AddError::Invalid);
1361 }
1362 for ip_range in &self.allowed_ip_ranges {
1363 if self.denied_ip_ranges.contains(ip_range) {
1364 return Err(AddError::AlreadyDenied);
1365 }
1366 }
1367 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1368 return Err(AddError::AlreadyDenied);
1369 }
1370 if utils::has_overlapping_ranges(&self.denied_ip_ranges) {
1372 return Err(AddError::Invalid);
1373 }
1374 for ip_range in &self.denied_ip_ranges {
1375 if self.allowed_ip_ranges.contains(ip_range) {
1376 return Err(AddError::AlreadyAllowed);
1377 }
1378 }
1379 if !utils::has_unique_elements(&self.static_dns_mapping) {
1380 return Err(AddError::AlreadyAllowed);
1381 }
1382 for host in self.static_dns_mapping.keys() {
1383 if !utils::authority::is_valid_host(host) {
1384 return Err(AddError::Invalid);
1385 }
1386 }
1387 if !utils::has_unique_elements(&self.allowed_url_paths) {
1388 return Err(AddError::AlreadyAllowed);
1389 }
1390 for url_path in &self.allowed_url_paths {
1391 if self.denied_url_paths.contains(url_path)
1392 || self.denied_url_paths_router.at(url_path).is_ok()
1393 {
1394 return Err(AddError::AlreadyDenied);
1395 } else if self.allowed_url_paths_router.at(url_path).is_ok() {
1396 return Err(AddError::AlreadyAllowed);
1397 } else {
1398 self.allowed_url_paths_router
1399 .insert(url_path.clone(), ())
1400 .map_err(|_| AddError::Invalid)?;
1401 }
1402 }
1403 if !utils::has_unique_elements(&self.denied_url_paths) {
1404 return Err(AddError::AlreadyDenied);
1405 }
1406 for url_path in &self.denied_url_paths {
1407 if self.allowed_url_paths.contains(url_path)
1408 || self.allowed_url_paths_router.at(url_path).is_ok()
1409 {
1410 return Err(AddError::AlreadyAllowed);
1411 } else if self.denied_url_paths_router.at(url_path).is_ok() {
1412 return Err(AddError::AlreadyDenied);
1413 } else {
1414 self.denied_url_paths_router
1415 .insert(url_path.clone(), ())
1416 .map_err(|_| AddError::Invalid)?;
1417 }
1418 }
1419 Ok(self.build())
1420 }
1421}