br_web_server/
lib.rs

1mod stream;
2pub mod config;
3pub mod request;
4pub mod response;
5pub mod websocket;
6#[cfg(feature = "pools")]
7mod pools;
8use crate::stream::{Scheme};
9use crate::config::{Config};
10use crate::request::{Request};
11use crate::response::Response;
12use crate::websocket::{CloseCode, ErrorCode, Message, Websocket};
13use log::{error, info, warn};
14use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
15use std::io::{BufReader, Error, Write};
16use std::net::{TcpListener};
17use std::sync::{Arc, Mutex};
18use std::time::{Duration};
19use std::{io, thread};
20use std::fmt::Debug;
21use std::path::PathBuf;
22use flate2::Compression;
23use flate2::write::GzEncoder;
24use json::{object, JsonValue};
25
26/// 网络服务
27#[derive(Clone, Debug)]
28pub struct WebServer;
29
30impl WebServer {
31    /// 后台服务器
32    pub fn new_service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) {
33        loop {
34            match WebServer::service(config.clone(), factory) {
35                Ok(()) => {}
36                Err(e) => error!("服务器错误: {}[{}]: {}", file!(), line!(), e),
37            }
38            warn!("服务器 1秒后重启");
39            thread::sleep(Duration::from_secs(1));
40        }
41    }
42    fn service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
43        info!("==================== 网络服务 服务信息 ====================");
44        info!("日志记录: {}",if config.log {"开启"} else {"关闭"});
45        info!("调试模式: {}",if config.debug { "开启" } else { "关闭" });
46        info!("监听地址: {}", config.host);
47        info!("服务地址: {}://{}",if config.https { "https" } else { "http" },config.host);
48        info!("根 目 录: {}", config.root_path.to_str().unwrap());
49        info!("访问目录: {}", config.public);
50        info!("运行目录: {}", config.runtime);
51        info!("SSL/TLS: {}",if config.https { "开启" } else { "关闭" });
52
53        if config.https {
54            info!("证书目录KEY: {:?}", config.tls.key);
55            info!("证书目录PEM: {:?}", config.tls.certs);
56        }
57
58        let listener = TcpListener::bind(config.host.clone())?;
59        info!("==================== 网络服务 启动成功 ====================");
60
61        let acceptor = Self::ssl(config.clone())?;
62        #[cfg(feature = "pools")] let mut pool = pools::Pool::new(config.pools_max * 4);
63        for stream in listener.incoming() {
64            match stream {
65                Ok(stream) => {
66                    let config_new = config.clone();
67                    let acceptor_new = acceptor.clone();
68                    #[cfg(not(feature = "pools"))]
69                    thread::spawn(move || {
70                        stream.set_nonblocking(false).unwrap();
71                        // 设置读取超时时间
72                        stream.set_read_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
73                        // 设置发送超时时间
74                        stream.set_write_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
75
76                        let scheme = if config_new.https {
77                            match acceptor_new.accept(stream) {
78                                Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
79                                Err(_) => return Err(Error::other("加载加密请求失败")),
80                            }
81                        } else {
82                            Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
83                        };
84
85                        let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
86                        let response = match request.handle() {
87                            Ok(()) => Response::new(request.clone(), factory),
88                            Err(e) => {
89                                error!("处理请求: {:?} {} {}",thread::current().id() ,e.code, e.body);
90                                return Err(Error::other(e.body.as_str()));
91                            }
92                        };
93                        match response.handle() {
94                            Ok(()) => {}
95                            Err(e) => {
96                                error!("发送错误失败2: {}",e.to_string());
97                                return Err(Error::other(e));
98                            }
99                        };
100                        match request.save_log() {
101                            Ok(()) => {}
102                            Err(_) => error!("日志记录错误")
103                        }
104                        Ok(())
105                    });
106
107                    #[cfg(feature = "pools")]
108                    pool.execute(move || -> io::Result<()> {
109
110                        // 设置读取超时时间
111                        stream.set_read_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
112                        // 设置发送超时时间
113                        stream.set_write_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
114
115
116                        let scheme = if config_new.https {
117                            match acceptor_new.accept(stream) {
118                                Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
119                                Err(_) => return Err(Error::other("加载加密请求失败")),
120                            }
121                        } else {
122                            Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
123                        };
124                        let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
125                        let request_req = request.handle();
126                        let mut response = Response::new(request.clone(), factory);
127                        match request_req {
128                            Ok(()) => {}
129                            Err(e) => return match response.status(e.code).txt(e.body.as_str()).send() {
130                                Ok(()) => Ok(()),
131                                Err(e) => Err(Error::other(e.body.as_str())),
132                            }
133                        };
134                        response.handle()?;
135                        match request.save_log() {
136                            Ok(()) => {}
137                            Err(_) => {
138                                error!("日志记录错误");
139                            }
140                        }
141                        Ok(())
142                    });
143                }
144                Err(e) => return Err(e),
145            }
146        }
147        #[cfg(feature = "pools")]
148        pool.end();
149        Ok(())
150    }
151
152    fn ssl(config: Config) -> io::Result<Arc<SslAcceptor>> {
153        if config.https {
154            let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
155            if !config.tls.key.is_file() {
156                return Err(Error::other(
157                    format!("private.key 不存在: {:?}", config.tls.key).as_str(),
158                ));
159            }
160            if !config.tls.certs.is_file() {
161                return Err(Error::other(
162                    format!("certificate.pem 不存在: {:?}", config.tls.certs).as_str(),
163                ));
164            }
165            acceptor.set_private_key_file(config.tls.key.clone(), SslFiletype::PEM)?;
166            acceptor.set_certificate_file(config.tls.certs.clone(), SslFiletype::PEM)?;
167            Ok(Arc::new(acceptor.build()))
168        } else {
169            Ok(Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls())?.build()))
170        }
171    }
172}
173
174pub trait HandlerClone {
175    fn clone_box(&self) -> Box<dyn Handler>;
176}
177
178/// 实现 HandlerClone for 所有 Handler + Clone 的实现者
179impl<T> HandlerClone for T
180where
181    T: 'static + Handler + Clone,
182{
183    fn clone_box(&self) -> Box<dyn Handler> {
184        Box::new(self.clone())
185    }
186}
187
188// 为 dyn Handler 实现 Clone
189impl Clone for Box<dyn Handler> {
190    fn clone(&self) -> Box<dyn Handler> {
191        self.clone_box()
192    }
193}
194pub trait Handler: Send + Sync + HandlerClone + Debug {
195    /// 请求 处理
196    fn on_request(&mut self, _request: Request, _response: &mut Response);
197    /// 预检请求处理 OPTIONS
198    fn on_options(&mut self, response: &mut Response) {
199        response.allow_origins = vec![];
200        response.allow_methods = vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"];
201        response.allow_headers = vec!["Authorization", "X-Forwarded-For", "X-Real-IP"];
202        response.header("Access-Control-Expose-Headers", "Content-Disposition");
203        response.header("Access-Control-Max-Age", 86400.to_string().as_str());
204    }
205    /// 响应 处理
206    fn on_response(&mut self, response: &mut Response) {
207        if !response.headers.has_key("Access-Control-Allow-Origin") {
208            response.header("Access-Control-Allow-Origin", "*");
209        }
210        // 允许前端跨域请求时发送和接收 cookie / 凭据
211        if !response.headers.has_key("Access-Control-Allow-Credentials") {
212            response.header("Access-Control-Allow-Credentials", "true");
213        }
214        // 允许前端读取指定请求头
215        if !response.headers.has_key("Access-Control-Expose-Headers") {
216            response.header("Access-Control-Expose-Headers", "Content-Disposition");
217        }
218    }
219
220    fn on_frame(&mut self) -> Result<(), HttpError> {
221        Ok(())
222    }
223    /// 握手监听
224    fn on_open(&mut self) -> Result<(), HttpError> {
225        Ok(())
226    }
227    /// 接收到消息
228    fn on_message(&mut self, _msg: Message) -> Result<(), HttpError> {
229        Ok(())
230    }
231    /// 关闭监听
232    fn on_close(&mut self, _code: CloseCode, _reason: &str) {}
233    /// 错误监听
234    fn on_error(&mut self, _err: ErrorCode) {}
235    /// 关机监听
236    fn on_shutdown(&mut self) {}
237}
238
239
240#[derive(Clone, Debug)]
241pub enum Connection {
242    /// 长连接
243    KeepAlive,
244    /// 短连接
245    Close,
246    Other(String),
247}
248impl Connection {
249    fn from(value: &str) -> Self {
250        match value.to_lowercase().as_str() {
251            "keep-alive" => Self::KeepAlive,
252            "close" => Self::Close,
253            _ => Self::Other(value.to_string()),
254        }
255    }
256    pub fn str(&self) -> &str {
257        match self {
258            Connection::KeepAlive => "keep-alive",
259            Connection::Close => "close",
260            Connection::Other(name) => name
261        }
262    }
263}
264#[derive(Clone, Debug)]
265pub enum Upgrade {
266    Websocket,
267    Http,
268    Other(String),
269}
270impl Upgrade {
271    fn from(name: &str) -> Self {
272        match name.to_lowercase().as_str() {
273            "websocket" => Self::Websocket,
274            "http" => Self::Http,
275            _ => Self::Other(name.to_lowercase().as_str().to_string()),
276        }
277    }
278    pub fn str(&self) -> &str {
279        match self {
280            Self::Websocket => "websocket",
281            Self::Http => "http",
282            Self::Other(name) => name,
283        }
284    }
285}
286
287/// 统一资源标识符
288#[derive(Clone, Debug)]
289#[derive(Default)]
290pub struct Uri {
291    /// 资源标识
292    pub uri: String,
293    /// 完整 url
294    pub url: String,
295    /// 查询字符串
296    pub query: String,
297    /// 片段或位置
298    pub fragment: String,
299    /// 资源路径
300    pub path: String,
301    /// 资源段落
302    pub path_segments: Vec<String>,
303}
304impl Uri {
305    pub fn from(url: &str) -> Self {
306        let mut decoded_url = br_crypto::encoding::urlencoding_decode(url);
307        let fragment = match decoded_url.rfind('#') {
308            None => String::new(),
309            Some(index) => decoded_url.drain(index..).collect::<String>(),
310        };
311
312        let query = match decoded_url.rfind('?') {
313            None => String::new(),
314            Some(index) => decoded_url.drain(index..).collect::<String>().trim_start_matches("?").to_string(),
315        };
316
317        let path_segments = decoded_url.split("/").map(|x| x.to_string()).filter(|x| !x.is_empty()).collect::<Vec<String>>();
318        Self {
319            uri: decoded_url.clone(),
320            url: url.to_string(),
321            query,
322            fragment,
323            path: decoded_url.clone(),
324            path_segments,
325        }
326    }
327    /// 获取请求参数
328    pub fn get_query_params(&self) -> JsonValue {
329        let text = self.query.split('&').collect::<Vec<&str>>();
330        let mut params = object! {};
331        for item in text {
332            if let Some(index) = item.find('=') {
333                let key = item[..index].to_string();
334                let value = item[index + 1..].to_string();
335                let _ = params.insert(key.as_str(), value);
336            }
337        }
338        params
339    }
340    #[must_use]
341    pub fn to_json(&self) -> JsonValue {
342        object! {
343            url: self.url.clone(),
344            query: self.query.clone(),
345            fragment: self.fragment.clone(),
346            path: self.path.clone(),
347            path_segments: self.path_segments.clone()
348        }
349    }
350}
351
352
353/// 请求方法
354#[derive(Clone, Debug)]
355pub enum Method {
356    /// 请求
357    POST,
358    /// 获取
359    GET,
360    /// 请求头
361    HEAD,
362    /// 更新
363    PUT,
364    /// 删除
365    DELETE,
366    /// 预请求
367    OPTIONS,
368    PATCH,
369    TRACE,
370    VIEW,
371    CONNECT,
372    PROPFIND,
373    /// http2.0
374    PRI,
375    /// 其他
376    Other(String),
377}
378
379impl Method {
380    #[must_use]
381    pub fn from(name: &str) -> Self {
382        match name.to_lowercase().as_str() {
383            "post" => Self::POST,
384            "get" => Self::GET,
385            "head" => Self::HEAD,
386            "put" => Self::PUT,
387            "delete" => Self::DELETE,
388            "options" => Self::OPTIONS,
389            "patch" => Self::PATCH,
390            "trace" => Self::TRACE,
391            "view" => Self::VIEW,
392            "propfind" => Self::PROPFIND,
393            "connect" => Self::CONNECT,
394            "pri" => Self::PRI,
395            _ => Self::Other(name.to_string()),
396        }
397    }
398    pub fn str(&mut self) -> &str {
399        match self {
400            Method::POST => "POST",
401            Method::GET => "GET",
402            Method::HEAD => "HEAD",
403            Method::PUT => "PUT",
404            Method::DELETE => "DELETE",
405            Method::OPTIONS => "OPTIONS",
406            Method::PATCH => "PATCH",
407            Method::TRACE => "TRACE",
408            Method::VIEW => "VIEW",
409            Method::PROPFIND => "PROPFIND",
410            Method::PRI => "PRI",
411            Method::CONNECT => "CONNECT",
412            Method::Other(e) => e
413        }
414    }
415}
416
417#[derive(Debug, Clone)]
418pub struct HttpError {
419    pub code: u16,
420    pub body: String,
421}
422
423impl HttpError {
424    /// 构造函数:用状态码和文本信息
425    pub fn new(code: u16, body: &str) -> Self {
426        Self {
427            code,
428            body: body.to_string(),
429        }
430    }
431}
432/// 内容类型
433#[derive(Debug, Clone)]
434pub enum ContentType {
435    FormData,
436    FormUrlencoded,
437    Json,
438    Xml,
439    Javascript,
440    Text,
441    Html,
442    Stream,
443    Other(String),
444}
445impl ContentType {
446    pub fn from(name: &str) -> Self {
447        match name {
448            "multipart/form-data" => Self::FormData,
449            "application/x-www-form-urlencoded" => Self::FormUrlencoded,
450            "application/json" => Self::Json,
451            "application/xml" | "text/xml" => Self::Xml,
452            "application/javascript" => Self::Javascript,
453            "application/octet-stream" => Self::Stream,
454            "text/html" => Self::Html,
455            "text/plain" => Self::Text,
456            _ => Self::Other(name.to_string()),
457        }
458    }
459    pub fn str(&self) -> &str {
460        match self {
461            ContentType::FormData => "multipart/form-data",
462            ContentType::FormUrlencoded => "application/x-www-form-urlencoded",
463            ContentType::Json => "application/json",
464            ContentType::Xml => "application/xml",
465            ContentType::Javascript => "application/javascript",
466            ContentType::Text => "text/plain",
467            ContentType::Html => "text/html",
468            ContentType::Other(name) => name.as_str(),
469            ContentType::Stream => "application/octet-stream"
470        }
471    }
472}
473/// 认证
474#[derive(Clone, Debug)]
475pub enum Authorization {
476    Basic(String, String),
477    Bearer(String),
478    Digest(JsonValue),
479    Other(String),
480}
481impl Authorization {
482    #[must_use]
483    pub fn from(data: &str) -> Self {
484        let authorization = data.split_whitespace().collect::<Vec<&str>>();
485        let mode = authorization[0].to_lowercase();
486        match mode.as_str() {
487            "basic" => {
488                let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
489                let text: Vec<&str> = text.split(':').collect();
490                Self::Basic(text[0].to_string(), text[1].to_string())
491            }
492            "bearer" => Self::Bearer(authorization[1].to_string()),
493            "digest" => {
494                let text = authorization[1..].concat().clone();
495                let text = text.split(',').collect::<Vec<&str>>();
496                let mut params = object! {};
497                for item in &text {
498                    let Some(index) = item.find('=') else { continue };
499                    let key = item[..index].to_string();
500                    let value = item[index + 2..item.len() - 1].to_string();
501                    let _ = params.insert(key.as_str(), value);
502                }
503                Self::Digest(params)
504            }
505            _ => Self::Other(data.to_string())
506        }
507    }
508    pub fn str(&mut self) -> JsonValue {
509        match self {
510            Authorization::Basic(key, value) => {
511                let mut data = object! {};
512                data[key.as_str()] = value.clone().into();
513                data
514            }
515            Authorization::Bearer(e) => e.clone().into(),
516            Authorization::Digest(e) => e.clone(),
517            Authorization::Other(name) => name.clone().into(),
518        }
519    }
520}
521/// 消息内容
522#[derive(Clone, Debug)]
523pub enum Content {
524    FormUrlencoded(JsonValue),
525    FormData(JsonValue),
526    Json(JsonValue),
527    Text(JsonValue),
528    Xml(JsonValue),
529    None,
530}
531impl Content {}
532#[derive(Clone, Debug)]
533pub enum FormData {
534    File(String, PathBuf),
535    Field(JsonValue),
536}
537
538/// 语言
539#[derive(Clone, Debug)]
540pub enum Language {
541    ZhCN,
542    ZhHans,
543    En,
544    Other(String),
545
546}
547impl Language {
548    #[must_use]
549    pub fn from(name: &str) -> Self {
550        let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
551        let name = binding.as_str();
552        match name {
553            "zh-cn" => Self::ZhCN,
554            "zh-hans" => Self::ZhHans,
555            "en" => Self::En,
556            _ => Self::Other(name.to_string()),
557        }
558    }
559    #[must_use]
560    pub fn str(&self) -> &str {
561        match self {
562            Language::ZhCN => "zh-CN",
563            Language::ZhHans => "zh-Hans",
564            Language::En => "en",
565            Language::Other(e) => e.as_str(),
566        }
567    }
568}
569
570
571/// 压缩方式
572#[derive(Clone, Debug)]
573pub enum Encoding {
574    Gzip,
575    Deflate,
576    Br,
577    Bzip2,
578    None,
579}
580impl Encoding {
581    #[must_use]
582    pub fn from(s: &str) -> Encoding {
583        match s.to_lowercase().as_str() {
584            x if x.contains("gzip") => Encoding::Gzip,
585            x if x.contains("deflate") => Encoding::Deflate,
586            x if x.contains("br") => Encoding::Br,
587            x if x.contains("bzip2") => Encoding::Bzip2,
588            _ => Encoding::None,
589        }
590    }
591    #[must_use]
592    pub fn str(&self) -> &str {
593        match self {
594            Encoding::Gzip => "gzip",
595            Encoding::Deflate => "deflate",
596            Encoding::Br => "br",
597            Encoding::None => "",
598            Encoding::Bzip2 => "bzip2",
599        }
600    }
601    pub fn compress(self, data: &[u8]) -> io::Result<Vec<u8>> {
602        match self {
603            Encoding::Gzip => {
604                let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
605                encoder.write_all(data)?;
606                encoder.finish()
607            }
608            _ => Ok(data.to_vec()),
609        }
610    }
611}