Skip to main content

br_web_server/
config.rs

1use json::{object, JsonValue};
2use serde::{Deserialize, Serialize};
3use std::fs;
4use std::path::{Path, PathBuf};
5
6#[derive(Debug, Clone, Deserialize, Serialize)]
7pub struct Config {
8    /// 调试
9    pub debug: bool,
10    /// 主机
11    pub host: String,
12    /// SSL/TLS
13    pub https: bool,
14    pub tls: TlsConfig,
15    /// 日志记录
16    pub log: bool,
17    /// 运行根目录
18    pub root_path: PathBuf,
19    /// 公开目录
20    pub public: String,
21    /// 网页目录
22    pub webpage: String,
23    /// 运行时目录
24    pub runtime: String,
25    /// 语言
26    pub charset: String,
27    /// 密钥token
28    pub token: String,
29    /// 密钥文件路径
30    pub pub_key_path: String,
31    /// 最大请求体大小 (字节),默认 10MB
32    #[serde(default = "default_max_body_size")]
33    pub max_body_size: usize,
34    /// 读取超时 (秒)
35    #[serde(default = "default_read_timeout")]
36    pub read_timeout: u64,
37    /// 写入超时 (秒)
38    #[serde(default = "default_write_timeout")]
39    pub write_timeout: u64,
40    /// 最大连接数,默认 1024
41    #[serde(default = "default_max_connections")]
42    pub max_connections: usize,
43}
44
45fn default_max_body_size() -> usize {
46    10 * 1024 * 1024
47}
48
49fn default_read_timeout() -> u64 {
50    30
51}
52
53fn default_write_timeout() -> u64 {
54    30
55}
56
57fn default_max_connections() -> usize {
58    1024
59}
60impl Config {
61    #[must_use]
62    pub fn default(path: PathBuf) -> Self {
63        Self {
64            debug: true,
65            host: "0.0.0.0:3535".to_string(),
66            https: false,
67            tls: TlsConfig::new(),
68            log: true,
69            root_path: path,
70            public: "public".to_string(),
71            webpage: "spa".to_string(),
72            runtime: "runtime".to_string(),
73            charset: "utf-8".to_string(),
74            token: String::new(),
75            pub_key_path: String::new(),
76            max_body_size: default_max_body_size(),
77            read_timeout: default_read_timeout(),
78            write_timeout: default_write_timeout(),
79            max_connections: default_max_connections(),
80        }
81    }
82
83    #[must_use]
84    pub fn create(config_file: &Path, pkg_name: bool) -> Config {
85        let dir = config_file.parent().unwrap_or(Path::new(".")).to_path_buf();
86        #[derive(Clone, Debug, Deserialize, Serialize)]
87        pub struct ConfigPkg {
88            pub br_web_server: Config,
89        }
90        impl ConfigPkg {
91            pub fn new(dir: PathBuf) -> ConfigPkg {
92                Self {
93                    br_web_server: Config::default(dir),
94                }
95            }
96        }
97        let mut data = Config::default(dir.clone());
98        data.from();
99        match fs::read_to_string(config_file) {
100            Ok(e) => {
101                if pkg_name {
102                    match toml::from_str::<ConfigPkg>(&e) {
103                        Ok(cfg) => cfg.br_web_server,
104                        Err(_) => Config::default(dir),
105                    }
106                } else {
107                    data
108                }
109            }
110            Err(_) => {
111                if pkg_name {
112                    let data = ConfigPkg::new(dir);
113                    let _ = fs::create_dir_all(config_file.parent().unwrap_or(Path::new(".")));
114                    if let Ok(toml) = toml::to_string(&data) {
115                        let _ = fs::write(config_file.to_str().unwrap_or(""), toml);
116                    }
117                    data.br_web_server
118                } else {
119                    let data = Config::default(dir);
120                    let _ = fs::create_dir_all(config_file.parent().unwrap_or(Path::new(".")));
121                    if let Ok(toml) = toml::to_string(&data) {
122                        let _ = fs::write(config_file.to_str().unwrap_or(""), toml);
123                    }
124                    data
125                }
126            }
127        }
128    }
129    fn from(&mut self) -> &mut Config {
130        let root = self.root_path.clone();
131        let runtime = root
132            .join(self.runtime.clone())
133            .to_str()
134            .unwrap_or("")
135            .to_string();
136        let public = root
137            .join(self.public.clone())
138            .to_str()
139            .unwrap_or("")
140            .to_string();
141        let webpage = root.join("webpage").to_str().unwrap_or("").to_string();
142        let ssl = root.join("ssl").to_str().unwrap_or("").to_string();
143
144        let _ = fs::create_dir_all(ssl.clone());
145        let _ = fs::create_dir_all(runtime.clone());
146        let _ = fs::create_dir_all(public.clone());
147        let _ = fs::create_dir_all(webpage.clone());
148
149        self
150    }
151    #[must_use]
152    pub fn json(&self) -> JsonValue {
153        object! {
154            debug: self.debug,
155            log: self.log,
156            host: self.host.as_str(),
157            https: self.https,
158            root_path:self.root_path.to_str().unwrap_or(""),
159            public: self.public.as_str(),
160            webpage: self.webpage.as_str(),
161            runtime: self.runtime.as_str(),
162            charset: self.charset.as_str(),
163            token: self.token.as_str(),
164            pub_key_path: self.pub_key_path.as_str(),
165            max_body_size: self.max_body_size,
166            read_timeout: self.read_timeout,
167            write_timeout: self.write_timeout,
168            max_connections: self.max_connections,
169        }
170    }
171}
172
173#[derive(Clone, Debug, Deserialize, Serialize)]
174pub struct TlsConfig {
175    pub certs: PathBuf,
176    pub key: PathBuf,
177}
178impl TlsConfig {
179    fn new() -> Self {
180        Self {
181            certs: PathBuf::default(),
182            key: PathBuf::default(),
183        }
184    }
185    pub fn json(&self) -> JsonValue {
186        object! {
187            certs:self.certs.to_str().unwrap_or(""),
188            key: self.key.to_str().unwrap_or(""),
189        }
190    }
191    #[must_use]
192    pub fn from(value: &JsonValue, root: &Path) -> Self {
193        Self {
194            certs: root.join(value["certs"].as_str().unwrap_or("")),
195            key: root.join(value["key"].as_str().unwrap_or("")),
196        }
197    }
198}