br_web/
lib.rs

1use std::{fs, thread};
2use std::net::TcpListener;
3use std::path::{Path, PathBuf};
4use std::sync::Arc;
5use std::time::Duration;
6use json::{JsonValue};
7use log::{debug, error, info};
8use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
9use crate::config::Config;
10use crate::request::{Connection, Method, Request};
11use crate::response::Response;
12use std::process::{Command, exit};
13
14/// 配置
15mod config;
16/// 服务接收
17mod service;
18mod stream;
19pub mod request;
20pub mod response;
21pub mod content_type;
22mod web_socket_message;
23
24#[derive(Debug, Clone)]
25pub struct Web {
26    pub config: Config,
27}
28
29impl Web {
30    /// 构造
31    ///
32    /// * root_dir 根目录
33    /// * config_path 配置文件路径
34    pub fn new(root_dir: PathBuf, config_path: PathBuf) -> Self {
35        match fs::create_dir_all(config_path.parent().unwrap()) {
36            Ok(_) => {}
37            Err(e) => {
38                error!("{}",e.to_string());
39                exit(0);
40            }
41        };
42        let mut config = match fs::read_to_string(config_path.to_str().unwrap()) {
43            Ok(content) => {
44                match json::parse(content.as_str()) {
45                    Ok(e) => e,
46                    Err(_) => {
47                        let res = Config::default();
48                        let json = res.json();
49                        fs::write(config_path.to_str().unwrap(), json.to_string()).unwrap();
50                        json
51                    }
52                }
53            }
54            Err(_) => {
55                let res = Config::default();
56                let json = res.json();
57                fs::write(config_path.to_str().unwrap(), json.to_string()).unwrap();
58                json
59            }
60        };
61
62        if config["public"].is_empty() {
63            config["public"] = "public".into();
64        }
65        if config["runtime"].is_empty() {
66            config["runtime"] = "runtime".into();
67        }
68
69        config["root_dir"] = root_dir.to_str().unwrap().into();
70        config["public"] = root_dir.join(config["public"].as_str().unwrap_or("public")).to_str().unwrap().into();
71        config["runtime"] = root_dir.join(config["runtime"].as_str().unwrap_or("runtime")).to_str().unwrap().into();
72        let mut config = Config::from(config);
73
74        // 根据不同的操作系统选择合适的命令
75        let command_output = if cfg!(target_os = "windows") {
76            Command::new("ipconfig")
77                .args(["/all"])
78                .output()
79        } else if cfg!(target_os = "macos") {
80            Command::new("ipconfig").arg("getifaddr").arg("en0").output()
81        } else {
82            Command::new("curl")
83                .arg("ifconfig.me")
84                .output()
85        };
86
87        let ip = match command_output {
88            Ok(e) => {
89                if cfg!(target_os = "windows") {
90                    let output_str = String::from_utf8_lossy(&e.stdout);
91                    let mut ipname = "".to_string();
92                    for line in output_str.lines() {
93                        if line.contains("IPv4") {
94                            let parts: Vec<&str> = line.split(":").collect();
95                            if parts.len() == 2 {
96                                let ip = parts[1].trim();
97                                ipname = ip.chars().filter(|&c| c == '.' || c.is_ascii_digit()).collect::<String>();
98                            }
99                        }
100                    }
101                    ipname
102                } else {
103                    let output_str = String::from_utf8_lossy(&e.stdout);
104                    output_str.trim().to_string()
105                }
106            }
107            Err(_) => {
108                config.host.to_string()
109            }
110        };
111
112        config.url = if config.port.is_empty() {
113            format!("{}://{}", config.schema, ip)
114        } else {
115            format!("{}://{}:{}", config.schema, ip, config.port)
116        };
117
118        info!("======================================== Web Service ========================================");
119        info!("[ip]          IP: {}",ip);
120        info!("[port]       端口: {}",config.port);
121        info!("[addr]  服务器地址: {}:{}",ip,config.port);
122        info!("[url]     访问地址: {}", config.url);
123        info!("[public]  公共目录: {}", config.public);
124        info!("[runtime] 运行目录: {}", config.runtime);
125        info!("[schema]     协议: {}", config.schema);
126        info!("[ssl]     开启状态: {}", config.ssl);
127
128        if config.ssl {
129            info!("[pkey]       私钥: {}", config.ssl_pkey.clone());
130            info!("[certs]      证书: {}", config.ssl_certs.clone());
131        }
132
133        Self {
134            config: config.clone()
135        }
136    }
137    /// 获取本机真实IP
138    pub fn service(&mut self, factory: fn() -> Box<dyn Handler>) {
139        loop {
140            let listener = match TcpListener::bind(format!("{}:{}", self.config.host.clone(), self.config.port.clone()).as_str()) {
141                Ok(listener) => listener,
142                Err(e) => {
143                    error!("监听失败: {}", e.to_string());
144                    error!("服务器断线5秒后重启");
145                    thread::sleep(Duration::from_secs(5));
146                    continue;
147                }
148            };
149            info!("====================启动 {} 成功====================",self.config.url);
150
151            let ssl = match self.ssl() {
152                Ok(e) => e,
153                Err(_) => {
154                    error!("加密失败 服务器断线5秒后重启");
155                    thread::sleep(Duration::from_secs(5));
156                    continue;
157                }
158            };
159
160            for stream in listener.incoming() {
161                let stream = stream.unwrap();
162                stream.set_write_timeout(Option::from(Duration::from_secs(30))).expect("TODO: panic message");
163                let config = self.config.clone();
164                let ssl = ssl.clone();
165                let factorys = factory;
166
167                thread::spawn(move || {
168                    match service::Service::new(stream.try_clone().unwrap(), config.clone(), ssl.clone()) {
169                        Ok(mut service) => {
170                            let server_ip = stream.local_addr().unwrap().ip().to_string();
171                            let client_ip = stream.peer_addr().unwrap().ip().to_string();
172                            let mut request = match service.request_header() {
173                                Ok(e) => {
174                                    let mut req = match Request::new(config.clone(), e.clone()) {
175                                        Ok(e) => e,
176                                        Err(e) => return error!("IP: {} 请求头部解析错误: {}",client_ip,e)
177                                    };
178                                    req.server_ip = server_ip;
179                                    if req.client_ip.is_empty() {
180                                        req.client_ip = client_ip.clone();
181                                    }
182                                    if config.debug {
183                                        debug!("server_ip: {} client_ip: {} agent_ip: {}",req.server_ip,req.client_ip,req.agent_ip);
184                                    }
185                                    if config.log {
186                                        req.record_log();
187                                    }
188                                    // 源检查
189                                    req.allow_origin();
190                                    if !req.is_origin {
191                                        return error!("IP: {} 跨域拦截: {:?}",client_ip,req);
192                                    }
193                                    req
194                                }
195                                Err(e) => return error!("IP: {} 请求头部错误: {}",client_ip,e)
196                            };
197                            if request.content_length > request.content_body_length {
198                                let req_body = match service.request_body(request.content_length, request.body) {
199                                    Ok(e) => e,
200                                    Err(e) => {
201                                        return error!("IP: {} 请求内容错误: {}",client_ip,e);
202                                    }
203                                };
204                                request.body = req_body.clone();
205                                request.content_body_length = req_body.len();
206                                if config.debug {
207                                    let body = unsafe { String::from_utf8_unchecked(request.body.clone()) };
208                                    debug!("IP: {} 长度: {} 消息体: {}",client_ip,request.content_body_length,body);
209                                }
210                            }
211                            if request.content_length > 0 {
212                                let _ = request.body();
213                                {};
214                            }
215
216                            match request.connection {
217                                Connection::Upgrade => {
218                                    if request.upgrade.as_str() == "websocket" {
219                                        let mut res = Response::new(config.clone(), request.protocol.clone());
220                                        let res_text = res.websocket(request.sec_web_socket_key.clone());
221                                        match service.response(res_text.clone()) {
222                                            Ok(_) => {
223                                                if config.debug {
224                                                    debug!("连接WS成功: {}",res_text);
225                                                }
226                                                loop {
227                                                    match service.request_websocket() {
228                                                        Ok(e) => {
229                                                            info!("接收到消息 {:?}",e);
230                                                            continue;
231                                                        }
232                                                        Err(e) => {
233                                                            break error!("IP: {} 连线失败: {}",client_ip,e);
234                                                        }
235                                                    };
236                                                }
237                                            }
238                                            Err(e) => {
239                                                error!("IP: {} 发送错误: {}",client_ip,e.to_string())
240                                            }
241                                        }
242                                    }
243                                }
244                                _ => {
245                                    let mut res = Response::new(config.clone(), request.protocol.clone());
246                                    let res_text = match request.method {
247                                        Method::OPTIONS => {
248                                            res.options()
249                                        }
250                                        Method::None => {
251                                            return error!("错误请求: {:#}",request.json());
252                                        }
253                                        _ => {
254                                            let file = format!("{}{}", config.public.clone(), request.uri.clone());
255                                            let file_info = Path::new(file.as_str());
256                                            if file_info.is_file() {
257                                                res.file(file.clone())
258                                            } else {
259                                                let (types, data) = (factorys)().on_request(request.clone()).clone();
260                                                res.receipt(types, data)
261                                            }
262                                        }
263                                    };
264                                    match service.response(res_text.clone()) {
265                                        Ok(_) => {
266                                            if config.debug {
267                                                debug!("响应OK: {}",res_text);
268                                            }
269                                        }
270                                        Err(e) => {
271                                            error!("IP: {} 发送错误: {}",client_ip,e.to_string())
272                                        }
273                                    }
274                                }
275                            }
276                        }
277                        Err(e) => {
278                            error!("请求错误: {}",e)
279                        }
280                    }
281                });
282            }
283            error!("服务器断线5秒后重启");
284            thread::sleep(Duration::from_secs(5));
285        }
286    }
287    fn ssl(&mut self) -> Result<Arc<SslAcceptor>, String> {
288        let res = if self.config.ssl {
289            let mut acceptor = match SslAcceptor::mozilla_intermediate(SslMethod::tls()) {
290                Ok(e) => e,
291                Err(e) => {
292                    return Err(e.to_string());
293                }
294            };
295            match acceptor.set_private_key_file(self.config.ssl_pkey.clone(), SslFiletype::PEM) {
296                Ok(_) => {}
297                Err(e) => return Err(format!("加载私钥失败: {}", e))
298            }
299            match acceptor.set_certificate_file(self.config.ssl_certs.clone(), SslFiletype::PEM) {
300                Ok(_) => {}
301                Err(e) => return Err(format!("加载正式失败: {}", e))
302            }
303            Arc::new(acceptor.build())
304        } else {
305            Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap().build())
306        };
307        Ok(res)
308    }
309}
310
311/// 监听事件
312pub trait Handler {
313    /// 接收到请求
314    fn on_request(&mut self, mut req: Request) -> (&'static str, JsonValue) {
315        ("json", req.json())
316    }
317}