rust_web_server/entry_point/
mod.rs1#[cfg(test)]
2mod tests;
3pub mod command_line_args;
4pub mod config_file;
5pub mod environment_variables;
6
7
8use std::{env};
9use crate::virtual_host::VirtualHostConfig;
10
11use crate::entry_point::command_line_args::{override_environment_variables_from_command_line_args};
12use crate::entry_point::config_file::override_environment_variables_from_config;
13use crate::entry_point::environment_variables::read_system_environment_variables;
14
15#[derive(PartialEq, Eq, Clone, Debug)]
16pub struct Config {}
17
18impl Config {
19 pub const RWS_CONFIG_IP: &'static str = "RWS_CONFIG_IP";
20 pub const RWS_CONFIG_IP_DEFAULT_VALUE: &'static str = "0.0.0.0";
23
24 pub const RWS_CONFIG_LOG_FORMAT: &'static str = "RWS_CONFIG_LOG_FORMAT";
26 pub const RWS_CONFIG_LOG_FORMAT_DEFAULT_VALUE: &'static str = "json";
27
28 pub const RWS_CONFIG_PORT: &'static str = "RWS_CONFIG_PORT";
29 pub const RWS_CONFIG_PORT_DEFAULT_VALUE: &'static str = "7878";
30
31 pub const RWS_CONFIG_THREAD_COUNT: &'static str = "RWS_CONFIG_THREAD_COUNT";
32 pub const RWS_CONFIG_THREAD_COUNT_DEFAULT_VALUE: &'static str = "200";
33
34 pub const RWS_CONFIG_CORS_ALLOW_ALL: &'static str = "RWS_CONFIG_CORS_ALLOW_ALL";
35 pub const RWS_CONFIG_CORS_ALLOW_ALL_DEFAULT_VALUE: &'static str = "true";
36
37 pub const RWS_CONFIG_CORS_ALLOW_ORIGINS: &'static str = "RWS_CONFIG_CORS_ALLOW_ORIGINS";
38 pub const RWS_CONFIG_CORS_ALLOW_ORIGINS_DEFAULT_VALUE: &'static str = "";
39
40 pub const RWS_CONFIG_CORS_ALLOW_CREDENTIALS: &'static str = "RWS_CONFIG_CORS_ALLOW_CREDENTIALS";
41 pub const RWS_CONFIG_CORS_ALLOW_CREDENTIALS_DEFAULT_VALUE: &'static str = "";
42
43 pub const RWS_CONFIG_CORS_ALLOW_HEADERS: &'static str = "RWS_CONFIG_CORS_ALLOW_HEADERS";
44 pub const RWS_CONFIG_CORS_ALLOW_HEADERS_DEFAULT_VALUE: &'static str = "";
45
46 pub const RWS_CONFIG_CORS_ALLOW_METHODS: &'static str = "RWS_CONFIG_CORS_ALLOW_METHODS";
47 pub const RWS_CONFIG_CORS_ALLOW_METHODS_DEFAULT_VALUE: &'static str = "";
48
49 pub const RWS_CONFIG_CORS_EXPOSE_HEADERS: &'static str = "RWS_CONFIG_CORS_EXPOSE_HEADERS";
50 pub const RWS_CONFIG_CORS_EXPOSE_HEADERS_DEFAULT_VALUE: &'static str = "";
51
52 pub const RWS_CONFIG_CORS_MAX_AGE: &'static str = "RWS_CONFIG_CORS_MAX_AGE";
53 pub const RWS_CONFIG_CORS_MAX_AGE_DEFAULT_VALUE: &'static str = "86400";
54
55 pub const RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES: &'static str = "RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES";
56 pub const RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES_DEFAULT_VALUE: &'static str = "10000";
57
58 pub const RWS_CONFIG_MAX_BODY_SIZE_IN_BYTES: &'static str = "RWS_CONFIG_MAX_BODY_SIZE_IN_BYTES";
65 pub const RWS_CONFIG_MAX_BODY_SIZE_IN_BYTES_DEFAULT_VALUE: &'static str = "0";
66
67 pub const RWS_CONFIG_SPA_FALLBACK: &'static str = "RWS_CONFIG_SPA_FALLBACK";
74 pub const RWS_CONFIG_SPA_FALLBACK_DEFAULT_VALUE: &'static str = "";
75
76 pub const RWS_CONFIG_SPA_FALLBACK_EXCLUDE_PREFIXES: &'static str = "RWS_CONFIG_SPA_FALLBACK_EXCLUDE_PREFIXES";
80 pub const RWS_CONFIG_SPA_FALLBACK_EXCLUDE_PREFIXES_DEFAULT_VALUE: &'static str = "";
81
82 pub const RWS_CONFIG_TLS_CERT_FILE: &'static str = "RWS_CONFIG_TLS_CERT_FILE";
83 pub const RWS_CONFIG_TLS_CERT_FILE_DEFAULT_VALUE: &'static str = "";
84
85 pub const RWS_CONFIG_TLS_KEY_FILE: &'static str = "RWS_CONFIG_TLS_KEY_FILE";
86 pub const RWS_CONFIG_TLS_KEY_FILE_DEFAULT_VALUE: &'static str = "";
87
88 pub const RWS_CONFIG_TLS_CLIENT_CA_FILE: &'static str = "RWS_CONFIG_TLS_CLIENT_CA_FILE";
92 pub const RWS_CONFIG_TLS_CLIENT_CA_FILE_DEFAULT_VALUE: &'static str = "";
93
94 pub const RWS_CONFIG_TEMPLATE_DIR: &'static str = "RWS_CONFIG_TEMPLATE_DIR";
96 pub const RWS_CONFIG_TEMPLATE_DIR_DEFAULT_VALUE: &'static str = "templates";
97
98 pub const RWS_CONFIG_HTTP_REDIRECT_PORT: &'static str = "RWS_CONFIG_HTTP_REDIRECT_PORT";
101 pub const RWS_CONFIG_HTTP_REDIRECT_PORT_DEFAULT_VALUE: &'static str = "";
102
103 pub const RWS_CONFIG_ACME_DOMAINS: &'static str = "RWS_CONFIG_ACME_DOMAINS";
108 pub const RWS_CONFIG_ACME_DOMAINS_DEFAULT_VALUE: &'static str = "";
109
110 pub const RWS_CONFIG_ACME_EMAIL: &'static str = "RWS_CONFIG_ACME_EMAIL";
112 pub const RWS_CONFIG_ACME_EMAIL_DEFAULT_VALUE: &'static str = "";
113
114 pub const RWS_CONFIG_ACME_STAGING: &'static str = "RWS_CONFIG_ACME_STAGING";
116 pub const RWS_CONFIG_ACME_STAGING_DEFAULT_VALUE: &'static str = "false";
117
118 pub const RWS_CONFIG_ACME_DIRECTORY: &'static str = "RWS_CONFIG_ACME_DIRECTORY";
120 pub const RWS_CONFIG_ACME_DIRECTORY_DEFAULT_VALUE: &'static str = "";
121
122 pub const RWS_CONFIG_ACME_CERT_PATH: &'static str = "RWS_CONFIG_ACME_CERT_PATH";
125 pub const RWS_CONFIG_ACME_CERT_PATH_DEFAULT_VALUE: &'static str = "";
126
127 pub const RWS_CONFIG_ACME_KEY_PATH: &'static str = "RWS_CONFIG_ACME_KEY_PATH";
130 pub const RWS_CONFIG_ACME_KEY_PATH_DEFAULT_VALUE: &'static str = "";
131
132 pub const RWS_CONFIG_ACME_CHALLENGE_PORT: &'static str = "RWS_CONFIG_ACME_CHALLENGE_PORT";
135 pub const RWS_CONFIG_ACME_CHALLENGE_PORT_DEFAULT_VALUE: &'static str = "80";
136
137 pub const RWS_CONFIG_ACME_RENEW_BEFORE_DAYS: &'static str = "RWS_CONFIG_ACME_RENEW_BEFORE_DAYS";
139 pub const RWS_CONFIG_ACME_RENEW_BEFORE_DAYS_DEFAULT_VALUE: &'static str = "30";
140
141 pub const RWS_CONFIG_ACME_ACCOUNT_KEY_PATH: &'static str = "RWS_CONFIG_ACME_ACCOUNT_KEY_PATH";
143 pub const RWS_CONFIG_ACME_ACCOUNT_KEY_PATH_DEFAULT_VALUE: &'static str = "acme_account.key";
144
145 pub const RWS_CONFIG_ACME_CA_FILE: &'static str = "RWS_CONFIG_ACME_CA_FILE";
149 pub const RWS_CONFIG_ACME_CA_FILE_DEFAULT_VALUE: &'static str = "";
150
151 pub const RWS_CONFIG_ACME_RENEW_CHECK_INTERVAL_SECS: &'static str = "RWS_CONFIG_ACME_RENEW_CHECK_INTERVAL_SECS";
154 pub const RWS_CONFIG_ACME_RENEW_CHECK_INTERVAL_SECS_DEFAULT_VALUE: &'static str = "43200";
155
156
157 pub const RWS_DEFAULT_IP: &'static str = "127.0.0.1";
158 pub const RWS_DEFAULT_PORT: &'static i32 = &7878;
159 pub const RWS_DEFAULT_THREAD_COUNT: &'static i32 = &200;
160 pub const RWS_DEFAULT_REQUEST_ALLOCATION_SIZE_IN_BYTES: &'static i64 = &10000;
161
162
163}
164
165pub fn bootstrap() {
166 read_system_environment_variables();
167 override_environment_variables_from_config(None);
168 override_environment_variables_from_command_line_args();
169 crate::server_config::invalidate();
170}
171
172pub fn set_default_values() {
173 println!(" Initializing default values");
174
175 let is_var_set = env::var(Config::RWS_CONFIG_IP).is_ok();
176 if !is_var_set {
177 env::set_var(Config::RWS_CONFIG_IP, Config::RWS_CONFIG_IP_DEFAULT_VALUE);
178 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_IP, Config::RWS_CONFIG_IP_DEFAULT_VALUE);
179 } else {
180 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_IP);
181 }
182
183
184 let is_var_set = env::var(Config::RWS_CONFIG_PORT).is_ok();
185 if !is_var_set {
186 env::set_var(Config::RWS_CONFIG_PORT, Config::RWS_CONFIG_PORT_DEFAULT_VALUE);
187 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_PORT, Config::RWS_CONFIG_PORT_DEFAULT_VALUE);
188 } else {
189 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_PORT);
190 }
191
192 let is_var_set = env::var(Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES).is_ok();
193 if !is_var_set {
194 env::set_var(Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES, Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES_DEFAULT_VALUE);
195 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES, Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES_DEFAULT_VALUE);
196 } else {
197 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES);
198 }
199
200
201 let is_var_set = env::var(Config::RWS_CONFIG_THREAD_COUNT).is_ok();
202 if !is_var_set {
203 env::set_var(Config::RWS_CONFIG_THREAD_COUNT, Config::RWS_CONFIG_THREAD_COUNT_DEFAULT_VALUE);
204 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_THREAD_COUNT, Config::RWS_CONFIG_THREAD_COUNT_DEFAULT_VALUE);
205 } else {
206 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_THREAD_COUNT);
207 }
208
209 let is_var_set = env::var(Config::RWS_CONFIG_CORS_ALLOW_ALL).is_ok();
210 if !is_var_set {
211 env::set_var(Config::RWS_CONFIG_CORS_ALLOW_ALL, Config::RWS_CONFIG_CORS_ALLOW_ALL_DEFAULT_VALUE);
212 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_ALLOW_ALL, Config::RWS_CONFIG_CORS_ALLOW_ALL_DEFAULT_VALUE);
213 } else {
214 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_ALLOW_ALL);
215 }
216
217
218 let is_var_set = env::var(Config::RWS_CONFIG_CORS_ALLOW_ORIGINS).is_ok();
219 if !is_var_set {
220 env::set_var(Config::RWS_CONFIG_CORS_ALLOW_ORIGINS, Config::RWS_CONFIG_CORS_ALLOW_ORIGINS_DEFAULT_VALUE);
221 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_ALLOW_ORIGINS, Config::RWS_CONFIG_CORS_ALLOW_ORIGINS_DEFAULT_VALUE);
222 } else {
223 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_ALLOW_ORIGINS);
224 }
225
226 let is_var_set = env::var(Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS).is_ok();
227 if !is_var_set {
228 env::set_var(Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS, Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS_DEFAULT_VALUE);
229 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS, Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS_DEFAULT_VALUE);
230 } else {
231 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS);
232 }
233
234 let is_var_set = env::var(Config::RWS_CONFIG_CORS_ALLOW_HEADERS).is_ok();
235 if !is_var_set {
236 env::set_var(Config::RWS_CONFIG_CORS_ALLOW_HEADERS, Config::RWS_CONFIG_CORS_ALLOW_HEADERS_DEFAULT_VALUE);
237 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_ALLOW_HEADERS, Config::RWS_CONFIG_CORS_ALLOW_HEADERS_DEFAULT_VALUE);
238 } else {
239 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_ALLOW_HEADERS);
240 }
241
242
243 let is_var_set = env::var(Config::RWS_CONFIG_CORS_ALLOW_METHODS).is_ok();
244 if !is_var_set {
245 env::set_var(Config::RWS_CONFIG_CORS_ALLOW_METHODS, Config::RWS_CONFIG_CORS_ALLOW_METHODS_DEFAULT_VALUE);
246 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_ALLOW_METHODS, Config::RWS_CONFIG_CORS_ALLOW_METHODS_DEFAULT_VALUE);
247 } else {
248 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_ALLOW_METHODS);
249 }
250
251 let is_var_set = env::var(Config::RWS_CONFIG_CORS_EXPOSE_HEADERS).is_ok();
252 if !is_var_set {
253 env::set_var(Config::RWS_CONFIG_CORS_EXPOSE_HEADERS, Config::RWS_CONFIG_CORS_EXPOSE_HEADERS_DEFAULT_VALUE);
254 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_EXPOSE_HEADERS, Config::RWS_CONFIG_CORS_EXPOSE_HEADERS_DEFAULT_VALUE);
255 } else {
256 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_EXPOSE_HEADERS);
257 }
258
259 let is_var_set = env::var(Config::RWS_CONFIG_CORS_MAX_AGE).is_ok();
260 if !is_var_set {
261 env::set_var(Config::RWS_CONFIG_CORS_MAX_AGE, Config::RWS_CONFIG_CORS_MAX_AGE_DEFAULT_VALUE);
262 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_CORS_MAX_AGE, Config::RWS_CONFIG_CORS_MAX_AGE_DEFAULT_VALUE);
263 } else {
264 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_CORS_MAX_AGE);
265 }
266
267
268 let is_var_set = env::var(Config::RWS_CONFIG_TLS_CERT_FILE).is_ok();
269 if !is_var_set {
270 env::set_var(Config::RWS_CONFIG_TLS_CERT_FILE, Config::RWS_CONFIG_TLS_CERT_FILE_DEFAULT_VALUE);
271 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_TLS_CERT_FILE, Config::RWS_CONFIG_TLS_CERT_FILE_DEFAULT_VALUE);
272 } else {
273 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_TLS_CERT_FILE);
274 }
275
276 let is_var_set = env::var(Config::RWS_CONFIG_TLS_KEY_FILE).is_ok();
277 if !is_var_set {
278 env::set_var(Config::RWS_CONFIG_TLS_KEY_FILE, Config::RWS_CONFIG_TLS_KEY_FILE_DEFAULT_VALUE);
279 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_TLS_KEY_FILE, Config::RWS_CONFIG_TLS_KEY_FILE_DEFAULT_VALUE);
280 } else {
281 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_TLS_KEY_FILE);
282 }
283
284 let is_var_set = env::var(Config::RWS_CONFIG_HTTP_REDIRECT_PORT).is_ok();
285 if !is_var_set {
286 env::set_var(Config::RWS_CONFIG_HTTP_REDIRECT_PORT, Config::RWS_CONFIG_HTTP_REDIRECT_PORT_DEFAULT_VALUE);
287 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_HTTP_REDIRECT_PORT, Config::RWS_CONFIG_HTTP_REDIRECT_PORT_DEFAULT_VALUE);
288 } else {
289 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_HTTP_REDIRECT_PORT);
290 }
291
292 let is_var_set = env::var(Config::RWS_CONFIG_LOG_FORMAT).is_ok();
293 if !is_var_set {
294 env::set_var(Config::RWS_CONFIG_LOG_FORMAT, Config::RWS_CONFIG_LOG_FORMAT_DEFAULT_VALUE);
295 println!(" Default value for '{}' is '{}'", Config::RWS_CONFIG_LOG_FORMAT, Config::RWS_CONFIG_LOG_FORMAT_DEFAULT_VALUE);
296 } else {
297 println!(" There is an environment variable for '{}', default value won't be set", Config::RWS_CONFIG_LOG_FORMAT);
298 }
299
300 crate::server_config::invalidate();
301 println!(" End of initializing default values\n");
302}
303
304
305pub fn get_ip_port_thread_count() -> (String, i32, i32) {
306 let mut ip : String = Config::RWS_CONFIG_IP_DEFAULT_VALUE.to_string();
307 let mut port: i32 = *Config::RWS_DEFAULT_PORT;
308 let mut thread_count: i32 = *Config::RWS_DEFAULT_THREAD_COUNT;
309
310 let boxed_ip = env::var(Config::RWS_CONFIG_IP);
311 if boxed_ip.is_ok() {
312 ip = boxed_ip.unwrap()
313 }
314
315 let boxed_port = env::var(Config::RWS_CONFIG_PORT);
316 if boxed_port.is_ok() {
317 let _port = boxed_port.unwrap();
318 let boxed_parse = _port.parse::<i32>();
319 if boxed_parse.is_ok() {
320 port = boxed_parse.unwrap();
321 } else {
322 eprintln!("unable to parse port value, expected number, got {}, variable: {}",
323 _port, Config::RWS_CONFIG_PORT);
324 }
325 } else {
326 eprintln!("unable to parse port value, variable: {}", Config::RWS_CONFIG_PORT);
327 }
328
329 let boxed_thread_count = env::var(Config::RWS_CONFIG_THREAD_COUNT);
330 if boxed_thread_count.is_ok() {
331 let _thread_count = boxed_thread_count.unwrap();
332 let boxed_parse = _thread_count.parse();
333 if boxed_parse.is_ok() {
334 thread_count = boxed_parse.unwrap()
335 } else {
336 eprintln!("unable to parse thread count value, expected number, got {}, variable: {}",
337 thread_count, Config::RWS_CONFIG_THREAD_COUNT);
338 }
339
340 } else {
341 eprintln!("unable to parse thread count value, variable: {}", Config::RWS_CONFIG_THREAD_COUNT);
342 }
343
344 (ip, port, thread_count)
345}
346
347pub fn get_virtual_hosts() -> Vec<VirtualHostConfig> {
353 let mut hosts = Vec::new();
354 let mut i = 0usize;
355 loop {
356 match env::var(format!("RWS_CONFIG_VIRTUAL_HOST_{}_DOMAIN", i)) {
357 Err(_) => break,
358 Ok(domain) => {
359 let cert_file = env::var(format!("RWS_CONFIG_VIRTUAL_HOST_{}_CERT_FILE", i))
360 .unwrap_or_default();
361 let key_file = env::var(format!("RWS_CONFIG_VIRTUAL_HOST_{}_KEY_FILE", i))
362 .unwrap_or_default();
363 hosts.push(VirtualHostConfig { domain, cert_file, key_file });
364 i += 1;
365 }
366 }
367 }
368 hosts
369}
370
371pub fn get_request_allocation_size() -> i64 {
372 let mut request_allocation_size: i64 = *Config::RWS_DEFAULT_REQUEST_ALLOCATION_SIZE_IN_BYTES;
373
374 let boxed_port = env::var(Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES);
375 if boxed_port.is_ok() {
376 let _request_allocation_size = boxed_port.unwrap();
377 let boxed_parse = _request_allocation_size.parse::<i64>();
378 if boxed_parse.is_ok() {
379 request_allocation_size = boxed_parse.unwrap();
380 } else {
381 eprintln!("unable to parse port value, expected number, got {}, variable: {}",
382 _request_allocation_size, Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES);
383 }
384 } else {
385 eprintln!("unable to parse request allocation size value, variable: {}", Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES);
386 }
387
388
389 request_allocation_size
390}
391
392pub fn get_max_body_size() -> u64 {
396 env::var(Config::RWS_CONFIG_MAX_BODY_SIZE_IN_BYTES)
397 .ok()
398 .and_then(|v| v.parse::<u64>().ok())
399 .unwrap_or(0)
400}
401
402pub fn get_spa_fallback() -> Option<String> {
407 env::var(Config::RWS_CONFIG_SPA_FALLBACK).ok().filter(|v| !v.is_empty())
408}
409
410pub fn get_spa_fallback_exclude_prefixes() -> Vec<String> {
413 env::var(Config::RWS_CONFIG_SPA_FALLBACK_EXCLUDE_PREFIXES)
414 .ok()
415 .map(|v| v.split(',').map(|s| s.trim().to_string()).filter(|s| !s.is_empty()).collect())
416 .unwrap_or_default()
417}
418