ferron/util/
obtain_config_struct_vec.rs1use std::error::Error;
2use std::net::IpAddr;
3use std::slice::Iter;
4use std::sync::Arc;
5
6use crate::ferron_common::ServerConfig;
7use crate::ferron_util::ip_match::ip_match;
8use crate::ferron_util::match_hostname::match_hostname;
9use crate::ferron_util::match_location::match_location;
10
11pub struct ObtainConfigStructVec<T> {
12 global: Arc<Vec<T>>,
13 host: Arc<Vec<ObtainConfigStructVecHost<T>>>,
14}
15
16struct ObtainConfigStructVecHost<T> {
17 domain: Option<String>,
18 ip: Option<String>,
19 data: Vec<T>,
20 locations: Vec<ObtainConfigStructVecLocation<T>>,
21 error_configs: Vec<ObtainConfigStructVecErrorConfig<T>>,
22}
23
24struct ObtainConfigStructVecLocation<T> {
25 path: String,
26 data: Vec<T>,
27}
28
29struct ObtainConfigStructVecErrorConfig<T> {
30 scode: Option<u16>,
31 data: Vec<T>,
32}
33
34impl<T> ObtainConfigStructVec<T> {
35 pub fn new(
36 config: &ServerConfig,
37 mut execute_fn: impl FnMut(&ServerConfig) -> Result<Vec<T>, Box<dyn Error + Send + Sync>>,
38 ) -> Result<Self, Box<dyn Error + Send + Sync>> {
39 let global_struct = execute_fn(&config["global"])?;
40 let mut host_structs = Vec::new();
41
42 if let Some(hosts) = config["hosts"].as_vec() {
43 for host_yaml in hosts.iter() {
44 let domain = host_yaml["domain"].as_str().map(String::from);
45 let ip = host_yaml["ip"].as_str().map(String::from);
46 let mut error_configs = Vec::new();
47 let mut locations = Vec::new();
48 if let Some(error_configs_yaml) = host_yaml["errorConfig"].as_vec() {
49 for error_config_yaml in error_configs_yaml.iter() {
50 let scode = error_config_yaml["scode"].as_i64().map(|s| s as u16);
51 error_configs.push(ObtainConfigStructVecErrorConfig {
52 scode,
53 data: execute_fn(error_config_yaml)?,
54 });
55 }
56 }
57 if let Some(locations_yaml) = host_yaml["locations"].as_vec() {
58 for location_yaml in locations_yaml.iter() {
59 if let Some(path_str) = location_yaml["path"].as_str() {
60 let path = String::from(path_str);
61 locations.push(ObtainConfigStructVecLocation {
62 path,
63 data: execute_fn(location_yaml)?,
64 });
65 }
66 }
67 }
68 host_structs.push(ObtainConfigStructVecHost {
69 domain,
70 ip,
71 data: execute_fn(host_yaml)?,
72 locations,
73 error_configs,
74 });
75 }
76 }
77
78 Ok(Self {
79 global: Arc::new(global_struct),
80 host: Arc::new(host_structs),
81 })
82 }
83}
84
85impl<'a, T> ObtainConfigStructVec<T>
86where
87 T: 'a,
88{
89 pub fn obtain(
90 &'a self,
91 hostname: Option<&str>,
92 ip: IpAddr,
93 request_url: &str,
94 status_code: Option<u16>,
95 ) -> Vec<&'a T> {
96 let data_iter: Iter<'a, T> = self.global.iter();
97 let mut host_data_iter: Box<dyn Iterator<Item = &'a T>> = Box::new(vec![].into_iter());
98 let mut error_config_or_location_data_iter: Box<dyn Iterator<Item = &'a T>> =
99 Box::new(vec![].into_iter());
100
101 for host in self.host.iter() {
103 if match_hostname(
104 match &host.domain {
105 Some(value) => Some(value as &str),
106 None => None,
107 },
108 hostname,
109 ) && match &host.ip {
110 Some(value) => ip_match(value as &str, ip),
111 None => true,
112 } {
113 host_data_iter = Box::new(host.data.iter());
114 let mut error_config_used = false;
115 if let Some(status_code) = status_code {
116 for error_config in host.error_configs.iter() {
117 if error_config.scode.is_none() || error_config.scode == Some(status_code) {
118 error_config_or_location_data_iter = Box::new(error_config.data.iter());
119 error_config_used = true;
120 break;
121 }
122 }
123 }
124 if !error_config_used {
125 if let Ok(path_decoded) = urlencoding::decode(request_url) {
126 for location in host.locations.iter() {
127 if match_location(&location.path, &path_decoded) {
128 error_config_or_location_data_iter = Box::new(location.data.iter());
129 break;
130 }
131 }
132 }
133 }
134 break;
135 }
136 }
137
138 data_iter
139 .chain(host_data_iter)
140 .chain(error_config_or_location_data_iter)
141 .collect()
142 }
143}
144
145impl<T> Clone for ObtainConfigStructVec<T> {
146 fn clone(&self) -> Self {
147 Self {
148 global: self.global.clone(),
149 host: self.host.clone(),
150 }
151 }
152}