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;
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: Box<[HttpRequestMethod]>,
40 denied_methods: Box<[HttpRequestMethod]>,
41 allowed_hosts: Box<[Box<str>]>,
42 denied_hosts: Box<[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: vec![
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_boxed_slice(),
131 denied_methods: Vec::new().into_boxed_slice(),
132 allowed_hosts: Vec::new().into_boxed_slice(),
133 denied_hosts: Vec::new().into_boxed_slice(),
134 allowed_port_ranges: vec![80..=80, 443..=443].into_boxed_slice(),
135 denied_port_ranges: Vec::new().into_boxed_slice(),
136 allowed_ip_ranges: Vec::new().into_boxed_slice(),
137 denied_ip_ranges: Vec::new().into_boxed_slice(),
138 static_dns_mapping: HashMap::new(),
139 allowed_headers: HashMap::new(),
140 denied_headers: HashMap::new(),
141 allowed_url_paths_router: Router::new(),
142 denied_url_paths_router: Router::new(),
143 validate_fn: None,
144 allow_private_ip_ranges: false,
145 method_acl_default: false,
146 host_acl_default: false,
147 port_acl_default: false,
148 ip_acl_default: false,
149 header_acl_default: false,
150 url_path_acl_default: true,
151 }
152 }
153}
154
155impl HttpAcl {
156 pub fn builder() -> HttpAclBuilder {
158 HttpAclBuilder::new()
159 }
160
161 pub fn is_scheme_allowed(&self, scheme: &str) -> AclClassification {
163 if scheme == "http" && self.allow_http || scheme == "https" && self.allow_https {
164 AclClassification::AllowedUserAcl
165 } else {
166 AclClassification::DeniedUserAcl
167 }
168 }
169
170 pub fn is_method_allowed(&self, method: impl Into<HttpRequestMethod>) -> AclClassification {
172 let method = method.into();
173 if self.allowed_methods.contains(&method) {
174 AclClassification::AllowedUserAcl
175 } else if self.denied_methods.contains(&method) {
176 AclClassification::DeniedUserAcl
177 } else if self.method_acl_default {
178 AclClassification::AllowedDefault
179 } else {
180 AclClassification::DeniedDefault
181 }
182 }
183
184 pub fn is_host_allowed(&self, host: &str) -> AclClassification {
186 if self.denied_hosts.iter().any(|h| h.as_ref() == host) {
187 AclClassification::DeniedUserAcl
188 } else if self.allowed_hosts.iter().any(|h| h.as_ref() == host) {
189 AclClassification::AllowedUserAcl
190 } else if self.host_acl_default {
191 AclClassification::AllowedDefault
192 } else {
193 AclClassification::DeniedDefault
194 }
195 }
196
197 pub fn is_port_allowed(&self, port: u16) -> AclClassification {
199 if Self::is_port_in_ranges(port, &self.denied_port_ranges) {
200 AclClassification::DeniedUserAcl
201 } else if Self::is_port_in_ranges(port, &self.allowed_port_ranges) {
202 AclClassification::AllowedUserAcl
203 } else if self.port_acl_default {
204 AclClassification::AllowedDefault
205 } else {
206 AclClassification::DeniedDefault
207 }
208 }
209
210 pub fn is_ip_allowed(&self, ip: &IpAddr) -> AclClassification {
212 if (!utils::ip::is_global_ip(ip) || ip.is_loopback()) && !utils::ip::is_private_ip(ip) {
213 if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
214 return AclClassification::AllowedUserAcl;
215 } else {
216 return AclClassification::DeniedNotGlobal;
217 }
218 }
219
220 if Self::is_ip_in_ranges(ip, &self.allowed_ip_ranges) {
221 AclClassification::AllowedUserAcl
222 } else if Self::is_ip_in_ranges(ip, &self.denied_ip_ranges) {
223 AclClassification::DeniedUserAcl
224 } else if utils::ip::is_private_ip(ip) && !self.allow_private_ip_ranges {
225 AclClassification::DeniedPrivateRange
226 } else if self.ip_acl_default {
227 AclClassification::AllowedDefault
228 } else {
229 AclClassification::DeniedDefault
230 }
231 }
232
233 pub fn resolve_static_dns_mapping(&self, host: &str) -> Option<SocketAddr> {
235 self.static_dns_mapping.get(host).copied()
236 }
237
238 pub fn is_header_allowed(&self, header_name: &str, header_value: &str) -> AclClassification {
240 if let Some(allowed_value) = self.allowed_headers.get(header_name) {
241 if allowed_value.as_deref() == Some(header_value) || allowed_value.is_none() {
242 AclClassification::AllowedUserAcl
243 } else {
244 AclClassification::DeniedUserAcl
245 }
246 } else if let Some(denied_value) = self.denied_headers.get(header_name) {
247 if denied_value.as_deref() == Some(header_value) || denied_value.is_none() {
248 AclClassification::DeniedUserAcl
249 } else {
250 AclClassification::AllowedUserAcl
251 }
252 } else if self.header_acl_default {
253 AclClassification::AllowedDefault
254 } else {
255 AclClassification::DeniedDefault
256 }
257 }
258
259 pub fn is_url_path_allowed(&self, url_path: &str) -> AclClassification {
261 if self.allowed_url_paths_router.at(url_path).is_ok() {
262 AclClassification::AllowedUserAcl
263 } else if self.denied_url_paths_router.at(url_path).is_ok() {
264 AclClassification::DeniedUserAcl
265 } else if self.url_path_acl_default {
266 AclClassification::AllowedDefault
267 } else {
268 AclClassification::DeniedDefault
269 }
270 }
271
272 pub fn is_valid<'h>(
274 &self,
275 scheme: &str,
276 authority: &Authority,
277 headers: impl Iterator<Item = (&'h str, &'h str)> + Send + Sync + 'h,
278 body: Option<&[u8]>,
279 ) -> AclClassification {
280 if let Some(validate_fn) = &self.validate_fn {
281 validate_fn(scheme, authority, Box::new(headers), body)
282 } else {
283 AclClassification::AllowedDefault
284 }
285 }
286
287 fn is_ip_in_ranges(ip: &IpAddr, ranges: &[RangeInclusive<IpAddr>]) -> bool {
289 ranges.iter().any(|range| range.contains(ip))
290 }
291
292 fn is_port_in_ranges(port: u16, ranges: &[RangeInclusive<u16>]) -> bool {
294 ranges.iter().any(|range| range.contains(&port))
295 }
296}
297
298#[non_exhaustive]
300#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
301pub enum AclClassification {
302 AllowedUserAcl,
304 AllowedDefault,
306 DeniedUserAcl,
308 DeniedDefault,
310 Denied(String),
312 DeniedNotGlobal,
314 DeniedPrivateRange,
316}
317
318impl std::fmt::Display for AclClassification {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 match self {
321 AclClassification::AllowedUserAcl => {
322 write!(f, "The entiy is allowed according to the allowed ACL.")
323 }
324 AclClassification::AllowedDefault => write!(
325 f,
326 "The entity is allowed because the default is to allow if no ACL match is found."
327 ),
328 AclClassification::DeniedUserAcl => {
329 write!(f, "The entiy is denied according to the denied ACL.")
330 }
331 AclClassification::DeniedNotGlobal => {
332 write!(f, "The ip is denied because it is not global.")
333 }
334 AclClassification::DeniedPrivateRange => {
335 write!(f, "The ip is denied because it is in a private range.")
336 }
337 AclClassification::DeniedDefault => write!(
338 f,
339 "The entity is denied because the default is to deny if no ACL match is found."
340 ),
341 AclClassification::Denied(reason) => {
342 write!(f, "The entiy is denied because {}.", reason)
343 }
344 }
345 }
346}
347
348impl AclClassification {
349 pub fn is_allowed(&self) -> bool {
351 matches!(
352 self,
353 AclClassification::AllowedUserAcl | AclClassification::AllowedDefault
354 )
355 }
356
357 pub fn is_denied(&self) -> bool {
359 matches!(
360 self,
361 AclClassification::DeniedUserAcl
362 | AclClassification::Denied(_)
363 | AclClassification::DeniedDefault
364 | AclClassification::DeniedNotGlobal
365 | AclClassification::DeniedPrivateRange
366 )
367 }
368}
369
370#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
372#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
373pub enum HttpRequestMethod {
374 CONNECT,
376 DELETE,
378 GET,
380 HEAD,
382 OPTIONS,
384 PATCH,
386 POST,
388 PUT,
390 TRACE,
392 OTHER(Box<str>),
394}
395
396impl From<&str> for HttpRequestMethod {
397 fn from(method: &str) -> Self {
398 match method {
399 "CONNECT" => HttpRequestMethod::CONNECT,
400 "DELETE" => HttpRequestMethod::DELETE,
401 "GET" => HttpRequestMethod::GET,
402 "HEAD" => HttpRequestMethod::HEAD,
403 "OPTIONS" => HttpRequestMethod::OPTIONS,
404 "PATCH" => HttpRequestMethod::PATCH,
405 "POST" => HttpRequestMethod::POST,
406 "PUT" => HttpRequestMethod::PUT,
407 "TRACE" => HttpRequestMethod::TRACE,
408 _ => HttpRequestMethod::OTHER(method.into()),
409 }
410 }
411}
412
413impl HttpRequestMethod {
414 pub fn as_str(&self) -> &str {
416 match self {
417 HttpRequestMethod::CONNECT => "CONNECT",
418 HttpRequestMethod::DELETE => "DELETE",
419 HttpRequestMethod::GET => "GET",
420 HttpRequestMethod::HEAD => "HEAD",
421 HttpRequestMethod::OPTIONS => "OPTIONS",
422 HttpRequestMethod::PATCH => "PATCH",
423 HttpRequestMethod::POST => "POST",
424 HttpRequestMethod::PUT => "PUT",
425 HttpRequestMethod::TRACE => "TRACE",
426 HttpRequestMethod::OTHER(other) => other,
427 }
428 }
429}
430
431#[derive(Default, Clone)]
433#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
434pub struct HttpAclBuilder {
435 allow_http: bool,
436 allow_https: bool,
437 allowed_methods: Vec<HttpRequestMethod>,
438 denied_methods: Vec<HttpRequestMethod>,
439 allowed_hosts: Vec<String>,
440 denied_hosts: Vec<String>,
441 allowed_port_ranges: Vec<RangeInclusive<u16>>,
442 denied_port_ranges: Vec<RangeInclusive<u16>>,
443 allowed_ip_ranges: Vec<RangeInclusive<IpAddr>>,
444 denied_ip_ranges: Vec<RangeInclusive<IpAddr>>,
445 static_dns_mapping: HashMap<String, SocketAddr>,
446 allowed_headers: HashMap<String, Option<String>>,
447 denied_headers: HashMap<String, Option<String>>,
448 allowed_url_paths: Vec<String>,
449 #[cfg_attr(feature = "serde", serde(skip))]
450 allowed_url_paths_router: Router<()>,
451 denied_url_paths: Vec<String>,
452 #[cfg_attr(feature = "serde", serde(skip))]
453 denied_url_paths_router: Router<()>,
454 allow_private_ip_ranges: bool,
455 method_acl_default: bool,
456 host_acl_default: bool,
457 port_acl_default: bool,
458 ip_acl_default: bool,
459 header_acl_default: bool,
460 url_path_acl_default: bool,
461}
462
463impl std::fmt::Debug for HttpAclBuilder {
464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465 f.debug_struct("HttpAclBuilder")
466 .field("allow_http", &self.allow_http)
467 .field("allow_https", &self.allow_https)
468 .field("allowed_methods", &self.allowed_methods)
469 .field("denied_methods", &self.denied_methods)
470 .field("allowed_hosts", &self.allowed_hosts)
471 .field("denied_hosts", &self.denied_hosts)
472 .field("allowed_port_ranges", &self.allowed_port_ranges)
473 .field("denied_port_ranges", &self.denied_port_ranges)
474 .field("allowed_ip_ranges", &self.allowed_ip_ranges)
475 .field("denied_ip_ranges", &self.denied_ip_ranges)
476 .field("static_dns_mapping", &self.static_dns_mapping)
477 .field("allowed_headers", &self.allowed_headers)
478 .field("denied_headers", &self.denied_headers)
479 .field("allowed_url_paths", &self.allowed_url_paths)
480 .field("denied_url_paths", &self.denied_url_paths)
481 .field("allow_private_ip_ranges", &self.allow_private_ip_ranges)
482 .field("method_acl_default", &self.method_acl_default)
483 .field("host_acl_default", &self.host_acl_default)
484 .field("port_acl_default", &self.port_acl_default)
485 .field("ip_acl_default", &self.ip_acl_default)
486 .field("header_acl_default", &self.header_acl_default)
487 .field("url_path_acl_default", &self.url_path_acl_default)
488 .finish()
489 }
490}
491
492impl PartialEq for HttpAclBuilder {
493 fn eq(&self, other: &Self) -> bool {
494 self.allow_http == other.allow_http
495 && self.allow_https == other.allow_https
496 && self.allowed_methods == other.allowed_methods
497 && self.denied_methods == other.denied_methods
498 && self.allowed_hosts == other.allowed_hosts
499 && self.denied_hosts == other.denied_hosts
500 && self.allowed_port_ranges == other.allowed_port_ranges
501 && self.denied_port_ranges == other.denied_port_ranges
502 && self.allowed_ip_ranges == other.allowed_ip_ranges
503 && self.denied_ip_ranges == other.denied_ip_ranges
504 && self.static_dns_mapping == other.static_dns_mapping
505 && self.allowed_headers == other.allowed_headers
506 && self.denied_headers == other.denied_headers
507 && self.allowed_url_paths == other.allowed_url_paths
508 && self.denied_url_paths == other.denied_url_paths
509 && self.allow_private_ip_ranges == other.allow_private_ip_ranges
510 && self.method_acl_default == other.method_acl_default
511 && self.host_acl_default == other.host_acl_default
512 && self.port_acl_default == other.port_acl_default
513 && self.ip_acl_default == other.ip_acl_default
514 && self.header_acl_default == other.header_acl_default
515 && self.url_path_acl_default == other.url_path_acl_default
516 }
517}
518
519impl HttpAclBuilder {
520 pub fn new() -> Self {
522 Self {
523 allow_http: true,
524 allow_https: true,
525 allowed_methods: vec![
526 HttpRequestMethod::CONNECT,
527 HttpRequestMethod::DELETE,
528 HttpRequestMethod::GET,
529 HttpRequestMethod::HEAD,
530 HttpRequestMethod::OPTIONS,
531 HttpRequestMethod::PATCH,
532 HttpRequestMethod::POST,
533 HttpRequestMethod::PUT,
534 HttpRequestMethod::TRACE,
535 ],
536 denied_methods: Vec::new(),
537 allowed_hosts: Vec::new(),
538 denied_hosts: Vec::new(),
539 allowed_port_ranges: vec![80..=80, 443..=443],
540 denied_port_ranges: Vec::new(),
541 allowed_ip_ranges: Vec::new(),
542 denied_ip_ranges: Vec::new(),
543 allowed_headers: HashMap::new(),
544 denied_headers: HashMap::new(),
545 allowed_url_paths: Vec::new(),
546 allowed_url_paths_router: Router::new(),
547 denied_url_paths: Vec::new(),
548 denied_url_paths_router: Router::new(),
549 allow_private_ip_ranges: false,
550 static_dns_mapping: HashMap::new(),
551 method_acl_default: false,
552 host_acl_default: false,
553 port_acl_default: false,
554 ip_acl_default: false,
555 header_acl_default: false,
556 url_path_acl_default: true,
557 }
558 }
559
560 pub fn http(mut self, allow: bool) -> Self {
562 self.allow_http = allow;
563 self
564 }
565
566 pub fn https(mut self, allow: bool) -> Self {
568 self.allow_https = allow;
569 self
570 }
571
572 pub fn private_ip_ranges(mut self, allow: bool) -> Self {
574 self.allow_private_ip_ranges = allow;
575 self
576 }
577
578 pub fn method_acl_default(mut self, allow: bool) -> Self {
580 self.method_acl_default = allow;
581 self
582 }
583
584 pub fn host_acl_default(mut self, allow: bool) -> Self {
586 self.host_acl_default = allow;
587 self
588 }
589
590 pub fn port_acl_default(mut self, allow: bool) -> Self {
592 self.port_acl_default = allow;
593 self
594 }
595
596 pub fn ip_acl_default(mut self, allow: bool) -> Self {
598 self.ip_acl_default = allow;
599 self
600 }
601
602 pub fn header_acl_default(mut self, allow: bool) -> Self {
604 self.header_acl_default = allow;
605 self
606 }
607
608 pub fn url_path_acl_default(mut self, allow: bool) -> Self {
610 self.url_path_acl_default = allow;
611 self
612 }
613
614 pub fn add_allowed_method(
616 mut self,
617 method: impl Into<HttpRequestMethod>,
618 ) -> Result<Self, AddError> {
619 let method = method.into();
620 if self.denied_methods.contains(&method) {
621 Err(AddError::AlreadyDenied)
622 } else if self.allowed_methods.contains(&method) {
623 Err(AddError::AlreadyAllowed)
624 } else {
625 self.allowed_methods.push(method);
626 Ok(self)
627 }
628 }
629
630 pub fn remove_allowed_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
632 let method = method.into();
633 self.allowed_methods.retain(|m| m != &method);
634 self
635 }
636
637 pub fn allowed_methods(
639 mut self,
640 methods: Vec<impl Into<HttpRequestMethod>>,
641 ) -> Result<Self, AddError> {
642 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
643
644 for method in &methods {
645 if self.denied_methods.contains(method) {
646 return Err(AddError::AlreadyDenied);
647 } else if self.allowed_methods.contains(method) {
648 return Err(AddError::AlreadyAllowed);
649 }
650 }
651 self.allowed_methods = methods;
652 Ok(self)
653 }
654
655 pub fn clear_allowed_methods(mut self) -> Self {
657 self.allowed_methods.clear();
658 self
659 }
660
661 pub fn add_denied_method(
663 mut self,
664 method: impl Into<HttpRequestMethod>,
665 ) -> Result<Self, AddError> {
666 let method = method.into();
667 if self.allowed_methods.contains(&method) {
668 Err(AddError::AlreadyAllowed)
669 } else if self.denied_methods.contains(&method) {
670 Err(AddError::AlreadyDenied)
671 } else {
672 self.denied_methods.push(method);
673 Ok(self)
674 }
675 }
676
677 pub fn remove_denied_method(mut self, method: impl Into<HttpRequestMethod>) -> Self {
679 let method = method.into();
680 self.denied_methods.retain(|m| m != &method);
681 self
682 }
683
684 pub fn denied_methods(
686 mut self,
687 methods: Vec<impl Into<HttpRequestMethod>>,
688 ) -> Result<Self, AddError> {
689 let methods = methods.into_iter().map(|m| m.into()).collect::<Vec<_>>();
690
691 for method in &methods {
692 if self.allowed_methods.contains(method) {
693 return Err(AddError::AlreadyAllowed);
694 } else if self.denied_methods.contains(method) {
695 return Err(AddError::AlreadyDenied);
696 }
697 }
698 self.denied_methods = methods;
699 Ok(self)
700 }
701
702 pub fn clear_denied_methods(mut self) -> Self {
704 self.denied_methods.clear();
705 self
706 }
707
708 pub fn add_allowed_host(mut self, host: String) -> Result<Self, AddError> {
710 if utils::authority::is_valid_host(&host) {
711 if self.denied_hosts.contains(&host) {
712 Err(AddError::AlreadyDenied)
713 } else if self.allowed_hosts.contains(&host) {
714 Err(AddError::AlreadyAllowed)
715 } else {
716 self.allowed_hosts.push(host);
717 Ok(self)
718 }
719 } else {
720 Err(AddError::Invalid)
721 }
722 }
723
724 pub fn remove_allowed_host(mut self, host: String) -> Self {
726 self.allowed_hosts.retain(|h| h != &host);
727 self
728 }
729
730 pub fn allowed_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
732 for host in &hosts {
733 if utils::authority::is_valid_host(host) {
734 if self.denied_hosts.contains(host) {
735 return Err(AddError::AlreadyDenied);
736 } else if self.allowed_hosts.contains(host) {
737 return Err(AddError::AlreadyAllowed);
738 }
739 } else {
740 return Err(AddError::Invalid);
741 }
742 }
743 self.allowed_hosts = hosts;
744 Ok(self)
745 }
746
747 pub fn clear_allowed_hosts(mut self) -> Self {
749 self.allowed_hosts.clear();
750 self
751 }
752
753 pub fn add_denied_host(mut self, host: String) -> Result<Self, AddError> {
755 if utils::authority::is_valid_host(&host) {
756 if self.allowed_hosts.contains(&host) {
757 Err(AddError::AlreadyAllowed)
758 } else if self.denied_hosts.contains(&host) {
759 Err(AddError::AlreadyDenied)
760 } else {
761 self.denied_hosts.push(host);
762 Ok(self)
763 }
764 } else {
765 Err(AddError::Invalid)
766 }
767 }
768
769 pub fn remove_denied_host(mut self, host: String) -> Self {
771 self.denied_hosts.retain(|h| h != &host);
772 self
773 }
774
775 pub fn denied_hosts(mut self, hosts: Vec<String>) -> Result<Self, AddError> {
777 for host in &hosts {
778 if utils::authority::is_valid_host(host) {
779 if self.allowed_hosts.contains(host) {
780 return Err(AddError::AlreadyAllowed);
781 } else if self.denied_hosts.contains(host) {
782 return Err(AddError::AlreadyDenied);
783 }
784 } else {
785 return Err(AddError::Invalid);
786 }
787 }
788 self.denied_hosts = hosts;
789 Ok(self)
790 }
791
792 pub fn clear_denied_hosts(mut self) -> Self {
794 self.denied_hosts.clear();
795 self
796 }
797
798 pub fn add_allowed_port_range(
800 mut self,
801 port_range: RangeInclusive<u16>,
802 ) -> Result<Self, AddError> {
803 if self.denied_port_ranges.contains(&port_range) {
804 Err(AddError::AlreadyDenied)
805 } else if self.allowed_port_ranges.contains(&port_range) {
806 Err(AddError::AlreadyAllowed)
807 } else {
808 self.allowed_port_ranges.push(port_range);
809 Ok(self)
810 }
811 }
812
813 pub fn remove_allowed_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
815 self.allowed_port_ranges.retain(|p| p != &port_range);
816 self
817 }
818
819 pub fn allowed_port_ranges(
821 mut self,
822 port_ranges: Vec<RangeInclusive<u16>>,
823 ) -> Result<Self, AddError> {
824 for port_range in &port_ranges {
825 if self.denied_port_ranges.contains(port_range) {
826 return Err(AddError::AlreadyDenied);
827 } else if self.allowed_port_ranges.contains(port_range) {
828 return Err(AddError::AlreadyAllowed);
829 }
830 }
831 self.allowed_port_ranges = port_ranges;
832 Ok(self)
833 }
834
835 pub fn clear_allowed_port_ranges(mut self) -> Self {
837 self.allowed_port_ranges.clear();
838 self
839 }
840
841 pub fn add_denied_port_range(
843 mut self,
844 port_range: RangeInclusive<u16>,
845 ) -> Result<Self, AddError> {
846 if self.allowed_port_ranges.contains(&port_range) {
847 Err(AddError::AlreadyAllowed)
848 } else if self.denied_port_ranges.contains(&port_range) {
849 Err(AddError::AlreadyDenied)
850 } else {
851 self.denied_port_ranges.push(port_range);
852 Ok(self)
853 }
854 }
855
856 pub fn remove_denied_port_range(mut self, port_range: RangeInclusive<u16>) -> Self {
858 self.denied_port_ranges.retain(|p| p != &port_range);
859 self
860 }
861
862 pub fn denied_port_ranges(
864 mut self,
865 port_ranges: Vec<RangeInclusive<u16>>,
866 ) -> Result<Self, AddError> {
867 for port_range in &port_ranges {
868 if self.allowed_port_ranges.contains(port_range) {
869 return Err(AddError::AlreadyAllowed);
870 } else if self.denied_port_ranges.contains(port_range) {
871 return Err(AddError::AlreadyDenied);
872 }
873 }
874 self.denied_port_ranges = port_ranges;
875 Ok(self)
876 }
877
878 pub fn clear_denied_port_ranges(mut self) -> Self {
880 self.denied_port_ranges.clear();
881 self
882 }
883
884 pub fn add_allowed_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
886 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
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 self.allowed_ip_ranges.push(ip_range);
893 Ok(self)
894 }
895
896 pub fn remove_allowed_ip_range<Ip: IntoIpRange>(
898 mut self,
899 ip_range: Ip,
900 ) -> Result<Self, AddError> {
901 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
902 self.allowed_ip_ranges.retain(|ip| ip != &ip_range);
903 Ok(self)
904 }
905
906 pub fn allowed_ip_ranges<Ip: IntoIpRange>(
908 mut self,
909 ip_ranges: Vec<Ip>,
910 ) -> Result<Self, AddError> {
911 let ip_ranges = ip_ranges
912 .into_iter()
913 .map(|ip| ip.into_range())
914 .collect::<Option<Vec<_>>>()
915 .ok_or(AddError::Invalid)?;
916 for ip_range in &ip_ranges {
917 if self.denied_ip_ranges.contains(ip_range) {
918 return Err(AddError::AlreadyDenied);
919 } else if self.allowed_ip_ranges.contains(ip_range) {
920 return Err(AddError::AlreadyAllowed);
921 }
922 }
923 self.allowed_ip_ranges = ip_ranges;
924 Ok(self)
925 }
926
927 pub fn clear_allowed_ip_ranges(mut self) -> Self {
929 self.allowed_ip_ranges.clear();
930 self
931 }
932
933 pub fn add_denied_ip_range<Ip: IntoIpRange>(mut self, ip_range: Ip) -> Result<Self, AddError> {
935 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
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 self.denied_ip_ranges.push(ip_range);
942 Ok(self)
943 }
944
945 pub fn remove_denied_ip_range<Ip: IntoIpRange>(
947 mut self,
948 ip_range: Ip,
949 ) -> Result<Self, AddError> {
950 let ip_range = ip_range.into_range().ok_or(AddError::Invalid)?;
951 self.denied_ip_ranges.retain(|ip| ip != &ip_range);
952 Ok(self)
953 }
954
955 pub fn denied_ip_ranges<Ip: IntoIpRange>(
957 mut self,
958 ip_ranges: Vec<Ip>,
959 ) -> Result<Self, AddError> {
960 let ip_ranges = ip_ranges
961 .into_iter()
962 .map(|ip| ip.into_range())
963 .collect::<Option<Vec<_>>>()
964 .ok_or(AddError::Invalid)?;
965 for ip_range in &ip_ranges {
966 if self.allowed_ip_ranges.contains(ip_range) {
967 return Err(AddError::AlreadyAllowed);
968 } else if self.denied_ip_ranges.contains(ip_range) {
969 return Err(AddError::AlreadyDenied);
970 }
971 }
972 self.denied_ip_ranges = ip_ranges;
973 Ok(self)
974 }
975
976 pub fn clear_denied_ip_ranges(mut self) -> Self {
978 self.denied_ip_ranges.clear();
979 self
980 }
981
982 pub fn add_static_dns_mapping(
984 mut self,
985 host: String,
986 sock_addr: SocketAddr,
987 ) -> Result<Self, AddError> {
988 if utils::authority::is_valid_host(&host) {
989 self.static_dns_mapping.insert(host, sock_addr);
990 Ok(self)
991 } else {
992 Err(AddError::Invalid)
993 }
994 }
995
996 pub fn remove_static_dns_mapping(mut self, host: &str) -> Self {
998 self.static_dns_mapping.remove(host);
999 self
1000 }
1001
1002 pub fn static_dns_mappings(
1004 mut self,
1005 mappings: HashMap<String, SocketAddr>,
1006 ) -> Result<Self, AddError> {
1007 for (host, ip) in &mappings {
1008 if utils::authority::is_valid_host(host) {
1009 self.static_dns_mapping.insert(host.to_string(), *ip);
1010 } else {
1011 return Err(AddError::Invalid);
1012 }
1013 }
1014 Ok(self)
1015 }
1016
1017 pub fn clear_static_dns_mappings(mut self) -> Self {
1019 self.static_dns_mapping.clear();
1020 self
1021 }
1022
1023 pub fn add_allowed_header(
1025 mut self,
1026 header: String,
1027 value: Option<String>,
1028 ) -> Result<Self, AddError> {
1029 if self.denied_headers.contains_key(&header) {
1030 Err(AddError::AlreadyDenied)
1031 } else if let std::collections::hash_map::Entry::Vacant(e) =
1032 self.allowed_headers.entry(header)
1033 {
1034 e.insert(value);
1035 Ok(self)
1036 } else {
1037 Err(AddError::AlreadyAllowed)
1038 }
1039 }
1040
1041 pub fn remove_allowed_header(mut self, header: &str) -> Self {
1043 self.allowed_headers.remove(header);
1044 self
1045 }
1046
1047 pub fn allowed_headers(
1049 mut self,
1050 headers: HashMap<String, Option<String>>,
1051 ) -> Result<Self, AddError> {
1052 for header in headers.keys() {
1053 if self.denied_headers.contains_key(header) {
1054 return Err(AddError::AlreadyDenied);
1055 } else if self.allowed_headers.contains_key(header) {
1056 return Err(AddError::AlreadyAllowed);
1057 }
1058 }
1059 self.allowed_headers = headers;
1060 Ok(self)
1061 }
1062
1063 pub fn clear_allowed_headers(mut self) -> Self {
1065 self.allowed_headers.clear();
1066 self
1067 }
1068
1069 pub fn add_denied_header(
1071 mut self,
1072 header: String,
1073 value: Option<String>,
1074 ) -> Result<Self, AddError> {
1075 if self.allowed_headers.contains_key(&header) {
1076 Err(AddError::AlreadyAllowed)
1077 } else if let std::collections::hash_map::Entry::Vacant(e) =
1078 self.denied_headers.entry(header)
1079 {
1080 e.insert(value);
1081 Ok(self)
1082 } else {
1083 Err(AddError::AlreadyDenied)
1084 }
1085 }
1086
1087 pub fn remove_denied_header(mut self, header: &str) -> Self {
1089 self.denied_headers.remove(header);
1090 self
1091 }
1092
1093 pub fn denied_headers(
1095 mut self,
1096 headers: HashMap<String, Option<String>>,
1097 ) -> Result<Self, AddError> {
1098 for header in headers.keys() {
1099 if self.allowed_headers.contains_key(header) {
1100 return Err(AddError::AlreadyAllowed);
1101 } else if self.denied_headers.contains_key(header) {
1102 return Err(AddError::AlreadyDenied);
1103 }
1104 }
1105 self.denied_headers = headers;
1106 Ok(self)
1107 }
1108
1109 pub fn clear_denied_headers(mut self) -> Self {
1111 self.denied_headers.clear();
1112 self
1113 }
1114
1115 pub fn add_allowed_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1117 if self.denied_url_paths.contains(&url_path)
1118 || self.denied_url_paths_router.at(&url_path).is_ok()
1119 {
1120 Err(AddError::AlreadyDenied)
1121 } else if self.allowed_url_paths.contains(&url_path)
1122 || self.allowed_url_paths_router.at(&url_path).is_ok()
1123 {
1124 Err(AddError::AlreadyAllowed)
1125 } else {
1126 self.allowed_url_paths.push(url_path.clone());
1127 self.allowed_url_paths_router
1128 .insert(url_path, ())
1129 .map_err(|_| AddError::Invalid)?;
1130 Ok(self)
1131 }
1132 }
1133
1134 pub fn remove_allowed_url_path(mut self, url_path: &str) -> Self {
1136 self.allowed_url_paths.retain(|p| p != url_path);
1137 self.allowed_url_paths_router = {
1138 let mut router = Router::new();
1139 for url_path in &self.allowed_url_paths {
1140 router
1141 .insert(url_path.clone(), ())
1142 .expect("failed to insert url path");
1143 }
1144 router
1145 };
1146 self
1147 }
1148
1149 pub fn allowed_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1151 for url_path in &url_paths {
1152 if self.denied_url_paths.contains(url_path)
1153 || self.denied_url_paths_router.at(url_path).is_ok()
1154 {
1155 return Err(AddError::AlreadyDenied);
1156 } else if self.allowed_url_paths.contains(url_path)
1157 || self.allowed_url_paths_router.at(url_path).is_ok()
1158 {
1159 return Err(AddError::AlreadyAllowed);
1160 }
1161 }
1162 for url_path in &url_paths {
1163 self.allowed_url_paths_router
1164 .insert(url_path.clone(), ())
1165 .map_err(|_| AddError::Invalid)?;
1166 }
1167 self.allowed_url_paths = url_paths;
1168 Ok(self)
1169 }
1170
1171 pub fn clear_allowed_url_paths(mut self) -> Self {
1173 self.allowed_url_paths.clear();
1174 self.allowed_url_paths_router = Router::new();
1175 self
1176 }
1177
1178 pub fn add_denied_url_path(mut self, url_path: String) -> Result<Self, AddError> {
1180 if self.allowed_url_paths.contains(&url_path)
1181 || self.allowed_url_paths_router.at(&url_path).is_ok()
1182 {
1183 Err(AddError::AlreadyAllowed)
1184 } else if self.denied_url_paths.contains(&url_path)
1185 || self.denied_url_paths_router.at(&url_path).is_ok()
1186 {
1187 Err(AddError::AlreadyDenied)
1188 } else {
1189 self.denied_url_paths.push(url_path.clone());
1190 self.denied_url_paths_router
1191 .insert(url_path, ())
1192 .map_err(|_| AddError::Invalid)?;
1193 Ok(self)
1194 }
1195 }
1196
1197 pub fn remove_denied_url_path(mut self, url_path: &str) -> Self {
1199 self.denied_url_paths.retain(|p| p != url_path);
1200 self.denied_url_paths_router = {
1201 let mut router = Router::new();
1202 for url_path in &self.denied_url_paths {
1203 router
1204 .insert(url_path.clone(), ())
1205 .expect("failed to insert url path");
1206 }
1207 router
1208 };
1209 self
1210 }
1211
1212 pub fn denied_url_paths(mut self, url_paths: Vec<String>) -> Result<Self, AddError> {
1214 for url_path in &url_paths {
1215 if self.allowed_url_paths.contains(url_path)
1216 || self.allowed_url_paths_router.at(url_path).is_ok()
1217 {
1218 return Err(AddError::AlreadyAllowed);
1219 } else if self.denied_url_paths.contains(url_path)
1220 || self.denied_url_paths_router.at(url_path).is_ok()
1221 {
1222 return Err(AddError::AlreadyDenied);
1223 }
1224 }
1225 for url_path in &url_paths {
1226 self.denied_url_paths_router
1227 .insert(url_path.clone(), ())
1228 .map_err(|_| AddError::Invalid)?;
1229 }
1230 self.denied_url_paths = url_paths;
1231 Ok(self)
1232 }
1233
1234 pub fn clear_denied_url_paths(mut self) -> Self {
1236 self.denied_url_paths.clear();
1237 self.denied_url_paths_router = Router::new();
1238 self
1239 }
1240
1241 pub fn build(self) -> HttpAcl {
1243 self.build_full(None)
1244 }
1245
1246 pub fn build_full(self, validate_fn: Option<ValidateFn>) -> HttpAcl {
1248 HttpAcl {
1249 allow_http: self.allow_http,
1250 allow_https: self.allow_https,
1251 allowed_methods: self.allowed_methods.into_boxed_slice(),
1252 denied_methods: self.denied_methods.into_boxed_slice(),
1253 allowed_hosts: self
1254 .allowed_hosts
1255 .into_iter()
1256 .map(|x| x.into_boxed_str())
1257 .collect(),
1258 denied_hosts: self
1259 .denied_hosts
1260 .into_iter()
1261 .map(|x| x.into_boxed_str())
1262 .collect(),
1263 allowed_port_ranges: self.allowed_port_ranges.into_boxed_slice(),
1264 denied_port_ranges: self.denied_port_ranges.into_boxed_slice(),
1265 allowed_ip_ranges: self.allowed_ip_ranges.into_boxed_slice(),
1266 denied_ip_ranges: self.denied_ip_ranges.into_boxed_slice(),
1267 allowed_headers: self
1268 .allowed_headers
1269 .into_iter()
1270 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1271 .collect(),
1272 denied_headers: self
1273 .denied_headers
1274 .into_iter()
1275 .map(|(k, v)| (k.into_boxed_str(), v.map(|s| s.into_boxed_str())))
1276 .collect(),
1277 allowed_url_paths_router: self.allowed_url_paths_router,
1278 denied_url_paths_router: self.denied_url_paths_router,
1279 static_dns_mapping: self
1280 .static_dns_mapping
1281 .into_iter()
1282 .map(|(k, v)| (k.into_boxed_str(), v))
1283 .collect(),
1284 validate_fn,
1285 allow_private_ip_ranges: self.allow_private_ip_ranges,
1286 method_acl_default: self.method_acl_default,
1287 host_acl_default: self.host_acl_default,
1288 port_acl_default: self.port_acl_default,
1289 ip_acl_default: self.ip_acl_default,
1290 header_acl_default: self.header_acl_default,
1291 url_path_acl_default: self.url_path_acl_default,
1292 }
1293 }
1294
1295 pub fn try_build(mut self) -> Result<HttpAcl, AddError> {
1298 if !utils::has_unique_elements(&self.allowed_methods) {
1299 return Err(AddError::AlreadyAllowed);
1300 }
1301 for method in &self.allowed_methods {
1302 if self.denied_methods.contains(method) {
1303 return Err(AddError::AlreadyDenied);
1304 }
1305 }
1306 if !utils::has_unique_elements(&self.denied_methods) {
1307 return Err(AddError::AlreadyDenied);
1308 }
1309 for method in &self.denied_methods {
1310 if self.allowed_methods.contains(method) {
1311 return Err(AddError::AlreadyAllowed);
1312 }
1313 }
1314 if !utils::has_unique_elements(&self.allowed_hosts) {
1315 return Err(AddError::AlreadyAllowed);
1316 }
1317 for host in &self.allowed_hosts {
1318 if utils::authority::is_valid_host(host) {
1319 return Err(AddError::Invalid);
1320 }
1321 if self.denied_hosts.contains(host) {
1322 return Err(AddError::AlreadyDenied);
1323 }
1324 }
1325 if !utils::has_unique_elements(&self.denied_hosts) {
1326 return Err(AddError::AlreadyDenied);
1327 }
1328 for host in &self.denied_hosts {
1329 if utils::authority::is_valid_host(host) {
1330 return Err(AddError::Invalid);
1331 }
1332 if self.allowed_hosts.contains(host) {
1333 return Err(AddError::AlreadyAllowed);
1334 }
1335 }
1336 if !utils::has_unique_elements(&self.allowed_port_ranges) {
1337 return Err(AddError::AlreadyAllowed);
1338 }
1339 for port_range in &self.allowed_port_ranges {
1340 if self.denied_port_ranges.contains(port_range) {
1341 return Err(AddError::AlreadyDenied);
1342 }
1343 }
1344 if !utils::has_unique_elements(&self.denied_port_ranges) {
1345 return Err(AddError::AlreadyDenied);
1346 }
1347 for port_range in &self.denied_port_ranges {
1348 if self.allowed_port_ranges.contains(port_range) {
1349 return Err(AddError::AlreadyAllowed);
1350 }
1351 }
1352 if !utils::has_unique_elements(&self.allowed_ip_ranges) {
1353 return Err(AddError::AlreadyAllowed);
1354 }
1355 for ip_range in &self.allowed_ip_ranges {
1356 if self.denied_ip_ranges.contains(ip_range) {
1357 return Err(AddError::AlreadyDenied);
1358 }
1359 }
1360 if !utils::has_unique_elements(&self.denied_ip_ranges) {
1361 return Err(AddError::AlreadyDenied);
1362 }
1363 for ip_range in &self.denied_ip_ranges {
1364 if self.allowed_ip_ranges.contains(ip_range) {
1365 return Err(AddError::AlreadyAllowed);
1366 }
1367 }
1368 if !utils::has_unique_elements(&self.static_dns_mapping) {
1369 return Err(AddError::AlreadyAllowed);
1370 }
1371 for host in self.static_dns_mapping.keys() {
1372 if !utils::authority::is_valid_host(host) {
1373 return Err(AddError::Invalid);
1374 }
1375 }
1376 if !utils::has_unique_elements(&self.allowed_url_paths) {
1377 return Err(AddError::AlreadyAllowed);
1378 }
1379 for url_path in &self.allowed_url_paths {
1380 if self.denied_url_paths.contains(url_path)
1381 || self.denied_url_paths_router.at(url_path).is_ok()
1382 {
1383 return Err(AddError::AlreadyDenied);
1384 } else if self.allowed_url_paths_router.at(url_path).is_ok() {
1385 return Err(AddError::AlreadyAllowed);
1386 } else {
1387 self.allowed_url_paths_router
1388 .insert(url_path.clone(), ())
1389 .map_err(|_| AddError::Invalid)?;
1390 }
1391 }
1392 if !utils::has_unique_elements(&self.denied_url_paths) {
1393 return Err(AddError::AlreadyDenied);
1394 }
1395 for url_path in &self.denied_url_paths {
1396 if self.allowed_url_paths.contains(url_path)
1397 || self.allowed_url_paths_router.at(url_path).is_ok()
1398 {
1399 return Err(AddError::AlreadyAllowed);
1400 } else if self.denied_url_paths_router.at(url_path).is_ok() {
1401 return Err(AddError::AlreadyDenied);
1402 } else {
1403 self.denied_url_paths_router
1404 .insert(url_path.clone(), ())
1405 .map_err(|_| AddError::Invalid)?;
1406 }
1407 }
1408 Ok(self.build())
1409 }
1410}