rust_web_server/entry_point/command_line_args/
mod.rs1use std::env;
2use crate::entry_point::Config;
3
4#[cfg(test)]
5mod tests;
6
7pub fn override_environment_variables_from_command_line_args() {
8 println!("\n Start of Reading Command Line Arguments Section");
9
10 let args = env::args().collect();
11 let params = CommandLineArgument::get_command_line_arg_list();
12 CommandLineArgument::_parse(args, params);
13
14 println!(" End of Reading Command Line Arguments\n");
15}
16
17pub fn informational_flag_output(args: &[String]) -> Option<String> {
23 let flags = args.iter().skip(1);
24 for arg in flags {
25 match arg.as_str() {
26 "--version" | "-V" => {
27 return Some(format!("rws {}\n", env!("CARGO_PKG_VERSION")));
28 }
29 "--help" => return Some(help_text()),
30 _ => {}
31 }
32 }
33 None
34}
35
36fn help_text() -> String {
37 let mut text = format!(
38 "rws {} — HTTP/1.1, HTTP/2 and HTTP/3 web server and reverse proxy\n\n\
39 Usage: rws [OPTIONS]\n\n\
40 Serves the current directory on http://0.0.0.0:7878 by default. Drop an\n\
41 rws.config.toml with [[route]]/[[upstream]] sections in the working\n\
42 directory to run as a config-driven reverse proxy instead.\n\n\
43 Options (each also settable via the environment variable shown):\n",
44 env!("CARGO_PKG_VERSION")
45 );
46 for argument in CommandLineArgument::get_command_line_arg_list() {
47 let flag = format!("-{}, --{}=<value>", argument.short_form, argument.long_form);
48 let hint = argument._hint.unwrap_or_default();
49 text.push_str(&format!(" {:<44} {}\n {:<44} [env: {}]\n", flag, hint, "", argument.environment_variable));
50 }
51 text.push_str(" -V, --version Print version and exit\n");
52 text.push_str(" --help Print this help and exit\n\n");
53 text.push_str("Docs: https://rws8.tech\n");
54 text
55}
56
57pub struct CommandLineArgument {
58 pub short_form: String,
59 pub long_form: String,
60 pub environment_variable: String,
61 pub _hint: Option<String>,
62}
63
64impl CommandLineArgument {
65 pub fn get_command_line_arg_list() -> Vec<CommandLineArgument> {
66 let mut argument_list : Vec<CommandLineArgument> = vec![];
67
68 let argument = CommandLineArgument {
69 short_form: "p".to_string(),
70 long_form: "port".to_string(),
71 environment_variable: Config::RWS_CONFIG_PORT.to_string(),
72 _hint: Some("Port".to_string())
73 };
74 argument_list.push(argument);
75
76 let argument = CommandLineArgument {
77 short_form: "i".to_string(),
78 long_form: "ip".to_string(),
79 environment_variable: Config::RWS_CONFIG_IP.to_string(),
80 _hint: Some("IP or domain".to_string())
81 };
82 argument_list.push(argument);
83
84 let argument = CommandLineArgument {
85 short_form: "t".to_string(),
86 long_form: "thread-count".to_string(),
87 environment_variable: Config::RWS_CONFIG_THREAD_COUNT.to_string(),
88 _hint: Some("Number of threads".to_string())
89 };
90 argument_list.push(argument);
91
92
93 let argument = CommandLineArgument {
94 short_form: "a".to_string(),
95 long_form: "cors-allow-all".to_string(),
96 environment_variable: Config::RWS_CONFIG_CORS_ALLOW_ALL.to_string(),
97 _hint: Some("If set to true, will allow all CORS requests, other CORS properties will be ignored".to_string())
98 };
99 argument_list.push(argument);
100
101 let argument = CommandLineArgument {
102 short_form: "o".to_string(),
103 long_form: "cors-allow-origins".to_string(),
104 environment_variable: Config::RWS_CONFIG_CORS_ALLOW_ORIGINS.to_string(),
105 _hint: Some("Comma separated list of allowed origins, example: https://foo.example,https://bar.example".to_string())
106 };
107 argument_list.push(argument);
108
109 let argument = CommandLineArgument {
110 short_form: "m".to_string(),
111 long_form: "cors-allow-methods".to_string(),
112 environment_variable: Config::RWS_CONFIG_CORS_ALLOW_METHODS.to_string(),
113 _hint: Some("Comma separated list of allowed methods, example: POST,PUT".to_string())
114 };
115 argument_list.push(argument);
116
117 let argument = CommandLineArgument {
118 short_form: "h".to_string(),
119 long_form: "cors-allow-headers".to_string(),
120 environment_variable: Config::RWS_CONFIG_CORS_ALLOW_HEADERS.to_string(),
121 _hint: Some("Comma separated list of allowed request headers, in lowercase, example: content-type,x-custom-header".to_string())
122 };
123 argument_list.push(argument);
124
125 let argument = CommandLineArgument {
126 short_form: "c".to_string(),
127 long_form: "cors-allow-credentials".to_string(),
128 environment_variable: Config::RWS_CONFIG_CORS_ALLOW_CREDENTIALS.to_string(),
129 _hint: Some("If set to true, will allow to transmit credentials via CORS requests".to_string())
130 };
131 argument_list.push(argument);
132
133 let argument = CommandLineArgument {
134 short_form: "e".to_string(),
135 long_form: "cors-expose-headers".to_string(),
136 environment_variable: Config::RWS_CONFIG_CORS_EXPOSE_HEADERS.to_string(),
137 _hint: Some("Comma separated list of allowed response headers, in lowercase, example: content-type,x-custom-header".to_string())
138 };
139 argument_list.push(argument);
140
141 let argument = CommandLineArgument {
142 short_form: "g".to_string(),
143 long_form: "cors-max-age".to_string(),
144 environment_variable: Config::RWS_CONFIG_CORS_MAX_AGE.to_string(),
145 _hint: Some("How long results of preflight requests can be cached (in seconds)".to_string())
146 };
147 argument_list.push(argument);
148
149 let argument = CommandLineArgument {
150 short_form: "r".to_string(),
151 long_form: "request-allocation-size-in-bytes".to_string(),
152 environment_variable: Config::RWS_CONFIG_REQUEST_ALLOCATION_SIZE_IN_BYTES.to_string(),
153 _hint: Some("In bytes, how much memory to allocate for each request".to_string())
154 };
155 argument_list.push(argument);
156
157 let argument = CommandLineArgument {
158 short_form: "s".to_string(),
159 long_form: "tls-cert-file".to_string(),
160 environment_variable: Config::RWS_CONFIG_TLS_CERT_FILE.to_string(),
161 _hint: Some("Path to TLS certificate PEM file (enables HTTPS and HTTP/2)".to_string())
162 };
163 argument_list.push(argument);
164
165 let argument = CommandLineArgument {
166 short_form: "k".to_string(),
167 long_form: "tls-key-file".to_string(),
168 environment_variable: Config::RWS_CONFIG_TLS_KEY_FILE.to_string(),
169 _hint: Some("Path to TLS private key PEM file (enables HTTPS and HTTP/2)".to_string())
170 };
171 argument_list.push(argument);
172
173 argument_list
174 }
175
176 pub fn _parse(args: Vec<String>, argument_list : Vec<CommandLineArgument>) -> Vec<CommandLineArgument> {
177 for unparsed_argument in args.iter() {
178
179 let boxed_split = unparsed_argument.split_once('=');
180 if boxed_split.is_some() {
181
182 let (parameter, value) = boxed_split.unwrap();
183 println!("\n {}={}", parameter, value);
184 let boxed_predefined_argument =
185 argument_list
186 .iter()
187 .find(
188 |predefined_argument| {
189 let short_form = predefined_argument.short_form.to_string();
190 let long_form = predefined_argument.long_form.to_string();
191 let _param_short_form = ["-", &short_form].join("");
192 let _param_long_form = ["--", &long_form].join("");
193
194 parameter.eq(_param_short_form.as_str()) ||
195 parameter.eq(_param_long_form.as_str())
196 });
197 if boxed_predefined_argument.is_some() {
198 let predefined_argument = boxed_predefined_argument.unwrap();
199 CommandLineArgument::set_environment_variable(predefined_argument, value.to_string());
200 }
201
202 }
203 }
204 argument_list
205 }
206
207 pub fn set_environment_variable(argument: &CommandLineArgument, value: String) {
208 env::set_var(&argument.environment_variable, &value);
209 println!(" Set env variable '{}' to value '{}'", argument.environment_variable, &value);
210 }
211}