br-web 0.6.0

This is an WEB SERVER
Documentation
use std::{fs, thread};
use std::net::TcpListener;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
use json::{JsonValue};
use log::{debug, error, info};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use crate::config::Config;
use crate::request::{Connection, Method, Request};
use crate::response::Response;
use std::process::{Command, exit};

/// 配置
mod config;
/// 服务接收
mod service;
mod stream;
pub mod request;
pub mod response;
pub mod content_type;
mod web_socket_message;

#[derive(Debug, Clone)]
pub struct Web {
    pub config: Config,
}

impl Web {
    /// 构造
    ///
    /// * root_dir 根目录
    /// * config_path 配置文件路径
    pub fn new(root_dir: PathBuf, config_path: PathBuf) -> Self {
        match fs::create_dir_all(config_path.parent().unwrap()) {
            Ok(_) => {}
            Err(e) => {
                error!("{}",e.to_string());
                exit(0);
            }
        };
        let mut config = match fs::read_to_string(config_path.to_str().unwrap()) {
            Ok(content) => {
                match json::parse(content.as_str()) {
                    Ok(e) => e,
                    Err(_) => {
                        let res = Config::default();
                        let json = res.json();
                        fs::write(config_path.to_str().unwrap(), json.to_string()).unwrap();
                        json
                    }
                }
            }
            Err(_) => {
                let res = Config::default();
                let json = res.json();
                fs::write(config_path.to_str().unwrap(), json.to_string()).unwrap();
                json
            }
        };

        if config["public"].is_empty() {
            config["public"] = "public".into();
        }
        if config["runtime"].is_empty() {
            config["runtime"] = "runtime".into();
        }

        config["root_dir"] = root_dir.to_str().unwrap().into();
        config["public"] = root_dir.join(config["public"].as_str().unwrap_or("public")).to_str().unwrap().into();
        config["runtime"] = root_dir.join(config["runtime"].as_str().unwrap_or("runtime")).to_str().unwrap().into();
        let mut config = Config::from(config);

        // 根据不同的操作系统选择合适的命令
        let command_output = if cfg!(target_os = "windows") {
            Command::new("ipconfig")
                .args(["/all"])
                .output()
        } else if cfg!(target_os = "macos") {
            Command::new("ipconfig").arg("getifaddr").arg("en0").output()
        } else {
            Command::new("curl")
                .arg("ifconfig.me")
                .output()
        };

        let ip = match command_output {
            Ok(e) => {
                if cfg!(target_os = "windows") {
                    let output_str = String::from_utf8_lossy(&e.stdout);
                    let mut ipname = "".to_string();
                    for line in output_str.lines() {
                        if line.contains("IPv4") {
                            let parts: Vec<&str> = line.split(":").collect();
                            if parts.len() == 2 {
                                let ip = parts[1].trim();
                                ipname = ip.chars().filter(|&c| c == '.' || c.is_ascii_digit()).collect::<String>();
                            }
                        }
                    }
                    ipname
                } else {
                    let output_str = String::from_utf8_lossy(&e.stdout);
                    output_str.trim().to_string()
                }
            }
            Err(_) => {
                config.host.to_string()
            }
        };

        config.url = if config.port.is_empty() {
            format!("{}://{}", config.schema, ip)
        } else {
            format!("{}://{}:{}", config.schema, ip, config.port)
        };

        info!("======================================== Web Service ========================================");
        info!("[ip]          IP: {}",ip);
        info!("[port]       端口: {}",config.port);
        info!("[addr]  服务器地址: {}:{}",ip,config.port);
        info!("[url]     访问地址: {}", config.url);
        info!("[public]  公共目录: {}", config.public);
        info!("[runtime] 运行目录: {}", config.runtime);
        info!("[schema]     协议: {}", config.schema);
        info!("[ssl]     开启状态: {}", config.ssl);

        if config.ssl {
            info!("[pkey]       私钥: {}", config.ssl_pkey.clone());
            info!("[certs]      证书: {}", config.ssl_certs.clone());
        }

        Self {
            config: config.clone()
        }
    }
    /// 获取本机真实IP
    pub fn service(&mut self, factory: fn() -> Box<dyn Handler>) {
        loop {
            let listener = match TcpListener::bind(format!("{}:{}", self.config.host.clone(), self.config.port.clone()).as_str()) {
                Ok(listener) => listener,
                Err(e) => {
                    error!("监听失败: {}", e.to_string());
                    error!("服务器断线5秒后重启");
                    thread::sleep(Duration::from_secs(5));
                    continue;
                }
            };
            info!("====================启动 {} 成功====================",self.config.url);

            let ssl = match self.ssl() {
                Ok(e) => e,
                Err(_) => {
                    error!("加密失败 服务器断线5秒后重启");
                    thread::sleep(Duration::from_secs(5));
                    continue;
                }
            };

            for stream in listener.incoming() {
                let stream = stream.unwrap();
                stream.set_write_timeout(Option::from(Duration::from_secs(30))).expect("TODO: panic message");
                let config = self.config.clone();
                let ssl = ssl.clone();
                let factorys = factory;

                thread::spawn(move || {
                    match service::Service::new(stream.try_clone().unwrap(), config.clone(), ssl.clone()) {
                        Ok(mut service) => {
                            let server_ip = stream.local_addr().unwrap().ip().to_string();
                            let client_ip = stream.peer_addr().unwrap().ip().to_string();
                            let mut request = match service.request_header() {
                                Ok(e) => {
                                    let mut req = match Request::new(config.clone(), e.clone()) {
                                        Ok(e) => e,
                                        Err(e) => return error!("IP: {} 请求头部解析错误: {}",client_ip,e)
                                    };
                                    req.server_ip = server_ip;
                                    if req.client_ip.is_empty() {
                                        req.client_ip = client_ip.clone();
                                    }
                                    if config.debug {
                                        debug!("server_ip: {} client_ip: {} agent_ip: {}",req.server_ip,req.client_ip,req.agent_ip);
                                    }
                                    if config.log {
                                        req.record_log();
                                    }
                                    // 源检查
                                    req.allow_origin();
                                    if !req.is_origin {
                                        return error!("IP: {} 跨域拦截: {:?}",client_ip,req);
                                    }
                                    req
                                }
                                Err(e) => return error!("IP: {} 请求头部错误: {}",client_ip,e)
                            };
                            if request.content_length > request.content_body_length {
                                let req_body = match service.request_body(request.content_length, request.body) {
                                    Ok(e) => e,
                                    Err(e) => {
                                        return error!("IP: {} 请求内容错误: {}",client_ip,e);
                                    }
                                };
                                request.body = req_body.clone();
                                request.content_body_length = req_body.len();
                                if config.debug {
                                    let body = unsafe { String::from_utf8_unchecked(request.body.clone()) };
                                    debug!("IP: {} 长度: {} 消息体: {}",client_ip,request.content_body_length,body);
                                }
                            }
                            if request.content_length > 0 {
                                let _ = request.body();
                                {};
                            }

                            match request.connection {
                                Connection::Upgrade => {
                                    if request.upgrade.as_str() == "websocket" {
                                        let mut res = Response::new(config.clone(), request.protocol.clone());
                                        let res_text = res.websocket(request.sec_web_socket_key.clone());
                                        match service.response(res_text.clone()) {
                                            Ok(_) => {
                                                if config.debug {
                                                    debug!("连接WS成功: {}",res_text);
                                                }
                                                loop {
                                                    match service.request_websocket() {
                                                        Ok(e) => {
                                                            info!("接收到消息 {:?}",e);
                                                            continue;
                                                        }
                                                        Err(e) => {
                                                            break error!("IP: {} 连线失败: {}",client_ip,e);
                                                        }
                                                    };
                                                }
                                            }
                                            Err(e) => {
                                                error!("IP: {} 发送错误: {}",client_ip,e.to_string())
                                            }
                                        }
                                    }
                                }
                                _ => {
                                    let mut res = Response::new(config.clone(), request.protocol.clone());
                                    let res_text = match request.method {
                                        Method::OPTIONS => {
                                            res.options()
                                        }
                                        Method::None => {
                                            return error!("错误请求: {:#}",request.json());
                                        }
                                        _ => {
                                            let file = format!("{}{}", config.public.clone(), request.uri.clone());
                                            let file_info = Path::new(file.as_str());
                                            if file_info.is_file() {
                                                res.file(file.clone())
                                            } else {
                                                let (types, data) = (factorys)().on_request(request.clone()).clone();
                                                res.receipt(types, data)
                                            }
                                        }
                                    };
                                    match service.response(res_text.clone()) {
                                        Ok(_) => {
                                            if config.debug {
                                                debug!("响应OK: {}",res_text);
                                            }
                                        }
                                        Err(e) => {
                                            error!("IP: {} 发送错误: {}",client_ip,e.to_string())
                                        }
                                    }
                                }
                            }
                        }
                        Err(e) => {
                            error!("请求错误: {}",e)
                        }
                    }
                });
            }
            error!("服务器断线5秒后重启");
            thread::sleep(Duration::from_secs(5));
        }
    }
    fn ssl(&mut self) -> Result<Arc<SslAcceptor>, String> {
        let res = if self.config.ssl {
            let mut acceptor = match SslAcceptor::mozilla_intermediate(SslMethod::tls()) {
                Ok(e) => e,
                Err(e) => {
                    return Err(e.to_string());
                }
            };
            match acceptor.set_private_key_file(self.config.ssl_pkey.clone(), SslFiletype::PEM) {
                Ok(_) => {}
                Err(e) => return Err(format!("加载私钥失败: {}", e))
            }
            match acceptor.set_certificate_file(self.config.ssl_certs.clone(), SslFiletype::PEM) {
                Ok(_) => {}
                Err(e) => return Err(format!("加载正式失败: {}", e))
            }
            Arc::new(acceptor.build())
        } else {
            Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap().build())
        };
        Ok(res)
    }
}

/// 监听事件
pub trait Handler {
    /// 接收到请求
    fn on_request(&mut self, mut req: Request) -> (&'static str, JsonValue) {
        ("json", req.json())
    }
}