br_web_server/
lib.rs

1mod stream;
2pub mod config;
3pub mod request;
4pub mod response;
5pub mod websocket;
6#[cfg(feature = "client")]
7pub mod client;
8mod url;
9mod client_response;
10
11use fs::read;
12use crate::stream::{Scheme};
13use crate::config::{Config};
14use crate::request::{Request};
15use crate::response::Response;
16use crate::websocket::{CloseCode, ErrorCode, Message, Websocket};
17use log::{error, info, warn};
18
19use rustls_pemfile::{certs};
20
21use std::io::{BufReader, Error, Read, Write};
22use std::net::{TcpListener};
23use std::sync::{Arc, Mutex};
24use std::time::{Duration};
25use std::{fs, io, thread};
26use std::fmt::Debug;
27use std::path::{PathBuf};
28use flate2::Compression;
29use flate2::read::GzDecoder;
30use flate2::write::GzEncoder;
31use json::{object, JsonValue};
32use rustls::{ServerConfig, ServerConnection, StreamOwned};
33
34/// 网络服务
35#[derive(Clone, Debug)]
36pub struct WebServer;
37
38impl WebServer {
39    /// 后台服务器
40    pub fn new_service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) {
41        loop {
42            match WebServer::service(config.clone(), factory) {
43                Ok(()) => {}
44                Err(e) => error!("服务器错误: {}[{}]: {}", file!(), line!(), e),
45            }
46            warn!("服务器 1秒后重启");
47            thread::sleep(Duration::from_secs(1));
48        }
49    }
50    fn service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
51        info!("==================== 网络服务 服务信息 ====================");
52        info!("日志记录: {}",if config.log {"开启"} else {"关闭"});
53        info!("调试模式: {}",if config.debug { "开启" } else { "关闭" });
54        info!("监听地址: {}", config.host);
55        info!("服务地址: {}://{}",if config.https { "https" } else { "http" },config.host);
56        info!("根 目 录: {}", config.root_path.to_str().unwrap());
57        info!("访问目录: {}", config.public);
58        info!("运行目录: {}", config.runtime);
59        info!("SSL/TLS: {}",if config.https { "开启" } else { "关闭" });
60
61        if config.https {
62            info!("证书目录KEY: {:?}", config.tls.key);
63            info!("证书目录PEM: {:?}", config.tls.certs);
64        }
65
66        let listener = TcpListener::bind(config.host.clone())?;
67        info!("==================== 网络服务 启动成功 ====================");
68
69        let acceptor = Self::ssl(config.clone())?;
70        for stream in listener.incoming() {
71            match stream {
72                Ok(stream) => {
73                    let config_new = config.clone();
74                    let acceptor_new = acceptor.clone();
75                    thread::spawn(move || -> io::Result<()> {
76                        stream.set_nonblocking(false)?;
77                        // 设置读取超时时间
78                        stream.set_read_timeout(Some(Duration::from_secs(30))).unwrap_or_default();
79                        // 设置发送超时时间
80                        stream.set_write_timeout(Some(Duration::from_secs(30))).unwrap_or_default();
81
82                        let scheme = if config_new.https {
83                            let conn = match ServerConnection::new(acceptor_new.unwrap()) {
84                                Ok(e) => e,
85                                Err(e) => {
86                                    return Err(Error::other(e.to_string()));
87                                }
88                            };
89                            Scheme::Https(Arc::new(Mutex::new(StreamOwned::new(conn, stream))))
90                        } else {
91                            Scheme::Http(Arc::new(Mutex::new(stream)))
92                        };
93
94
95                        let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
96                        let response = match request.handle() {
97                            Ok(()) => Response::new(&request.clone(), factory),
98                            Err(e) => {
99                                //error!("处理请求: {:?} {} {}",thread::current().id() ,e.code, e.body);
100                                return Err(Error::other(e.body.as_str()));
101                            }
102                        };
103                        match response.handle() {
104                            Ok(()) => {}
105                            Err(e) => {
106                                //error!("发送错误失败2: {}",e.to_string());
107                                return Err(Error::other(e));
108                            }
109                        };
110
111                        match request.save_log() {
112                            Ok(()) => {}
113                            Err(_) => error!("日志记录错误")
114                        }
115                        Ok(())
116                    });
117                }
118                Err(e) => return Err(e),
119            }
120        }
121        Ok(())
122    }
123    fn ssl(config: Config) -> io::Result<Option<Arc<ServerConfig>>> {
124        if config.https {
125            if !config.tls.key.is_file() {
126                return Err(Error::other(
127                    format!("private.key 不存在: {:?}", config.tls.key.clone()).as_str(),
128                ));
129            }
130            if !config.tls.certs.is_file() {
131                return Err(Error::other(
132                    format!("certificate.pem 不存在: {:?}", config.tls.certs).as_str(),
133                ));
134            }
135            let t = read(config.tls.key)?;
136            let mut reader = BufReader::new(t.as_slice());
137            let key = rustls_pemfile::private_key(&mut reader).unwrap().unwrap();
138            let t = read(config.tls.certs)?;
139            let mut reader = BufReader::new(t.as_slice());
140            let certs = certs(&mut reader).collect::<Result<Vec<_>, _>>()?.as_slice().to_owned();
141
142            let config = match ServerConfig::builder()
143                // 不需要客户端证书认证(单向 TLS),本地服务/一般 Web 服务都这么写
144                .with_no_client_auth()
145                // 配置“服务器证书链 + 服务器私钥”
146                .with_single_cert(certs, key) {
147                Ok(e) => e,
148                Err(e) => {
149                    return Err(Error::other(e))
150                }
151            };
152
153            Ok(Some(Arc::new(config)))
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(None)
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    H2c,
269    Other(String),
270}
271impl Upgrade {
272    fn from(name: &str) -> Self {
273        match name.to_lowercase().as_str() {
274            "websocket" => Upgrade::Websocket,
275            "http" => Upgrade::Http,
276            "h2c" => Upgrade::H2c,
277            _ => Upgrade::Other(name.to_lowercase().as_str().to_string()),
278        }
279    }
280    pub fn str(&self) -> &str {
281        match self {
282            Upgrade::Websocket => "websocket",
283            Upgrade::Http => "http",
284            Upgrade::H2c => "h2c",
285            Upgrade::Other(name) => name,
286        }
287    }
288}
289
290/// 统一资源标识符
291#[derive(Clone, Debug)]
292#[derive(Default)]
293pub struct Uri {
294    /// 资源标识
295    pub uri: String,
296    /// 完整 url
297    pub url: String,
298    /// 查询字符串
299    pub query: String,
300    /// 片段或位置
301    pub fragment: String,
302    /// 资源路径
303    pub path: String,
304    /// 资源段落
305    pub path_segments: Vec<String>,
306}
307impl Uri {
308    pub fn from(url: &str) -> Self {
309        let mut decoded_url = br_crypto::encoding::urlencoding_decode(url);
310        let fragment = match decoded_url.rfind('#') {
311            None => String::new(),
312            Some(index) => decoded_url.drain(index..).collect::<String>(),
313        };
314
315        let query = match decoded_url.rfind('?') {
316            None => String::new(),
317            Some(index) => decoded_url.drain(index..).collect::<String>().trim_start_matches("?").to_string(),
318        };
319
320        let path_segments = decoded_url.split('/').map(|x| x.to_string()).filter(|x| !x.is_empty()).collect::<Vec<String>>();
321        Self {
322            uri: decoded_url.clone(),
323            url: url.to_string(),
324            query,
325            fragment,
326            path: decoded_url.clone(),
327            path_segments,
328        }
329    }
330    /// 获取请求参数
331    #[must_use]
332    pub fn get_query_params(&self) -> JsonValue {
333        let text = self.query.split('&').collect::<Vec<&str>>();
334        let mut params = object! {};
335        for item in text {
336            if let Some(index) = item.find('=') {
337                let key = item[..index].to_string();
338                let value = item[index + 1..].to_string();
339                let _ = params.insert(key.as_str(), value);
340            }
341        }
342        params
343    }
344    #[must_use]
345    pub fn to_json(&self) -> JsonValue {
346        object! {
347            url: self.url.clone(),
348            query: self.query.clone(),
349            fragment: self.fragment.clone(),
350            path: self.path.clone(),
351            path_segments: self.path_segments.clone()
352        }
353    }
354}
355
356
357/// 请求方法
358#[derive(Clone, Debug)]
359pub enum Method {
360    /// 请求
361    POST,
362    /// 获取
363    GET,
364    /// 请求头
365    HEAD,
366    /// 更新
367    PUT,
368    /// 删除
369    DELETE,
370    /// 预请求
371    OPTIONS,
372    PATCH,
373    TRACE,
374    VIEW,
375    CONNECT,
376    PROPFIND,
377    /// http2.0
378    PRI,
379    /// 其他
380    Other(String),
381}
382
383impl Method {
384    #[must_use]
385    pub fn from(name: &str) -> Self {
386        match name.to_lowercase().as_str() {
387            "post" => Self::POST,
388            "get" => Self::GET,
389            "head" => Self::HEAD,
390            "put" => Self::PUT,
391            "delete" => Self::DELETE,
392            "options" => Self::OPTIONS,
393            "patch" => Self::PATCH,
394            "trace" => Self::TRACE,
395            "view" => Self::VIEW,
396            "propfind" => Self::PROPFIND,
397            "connect" => Self::CONNECT,
398            "pri" => Self::PRI,
399            _ => Self::Other(name.to_string()),
400        }
401    }
402    pub fn str(&mut self) -> &str {
403        match self {
404            Method::POST => "POST",
405            Method::GET => "GET",
406            Method::HEAD => "HEAD",
407            Method::PUT => "PUT",
408            Method::DELETE => "DELETE",
409            Method::OPTIONS => "OPTIONS",
410            Method::PATCH => "PATCH",
411            Method::TRACE => "TRACE",
412            Method::VIEW => "VIEW",
413            Method::PROPFIND => "PROPFIND",
414            Method::PRI => "PRI",
415            Method::CONNECT => "CONNECT",
416            Method::Other(e) => e.to_lowercase().leak()
417        }
418    }
419}
420
421#[derive(Debug, Clone)]
422pub struct HttpError {
423    pub code: u16,
424    pub body: String,
425}
426
427impl HttpError {
428    /// 构造函数:用状态码和文本信息
429    #[must_use]
430    pub fn new(code: u16, body: &str) -> Self {
431        Self {
432            code,
433            body: body.to_string(),
434        }
435    }
436}
437/// 内容类型
438#[derive(Debug, Clone)]
439pub enum ContentType {
440    FormData,
441    FormUrlencoded,
442    Json,
443    Xml,
444    Javascript,
445    Text,
446    Html,
447    Stream,
448    Other(String),
449}
450impl ContentType {
451    #[must_use]
452    pub fn from(name: &str) -> Self {
453        match name {
454            "multipart/form-data" => Self::FormData,
455            "application/x-www-form-urlencoded" => Self::FormUrlencoded,
456            "application/json" => Self::Json,
457            "application/xml" | "text/xml" => Self::Xml,
458            "application/javascript" => Self::Javascript,
459            "application/octet-stream" => Self::Stream,
460            "text/html" => Self::Html,
461            "text/plain" => Self::Text,
462            _ => Self::Other(name.to_string()),
463        }
464    }
465    #[must_use]
466    pub fn str(&self) -> &str {
467        match self {
468            ContentType::FormData => "multipart/form-data",
469            ContentType::FormUrlencoded => "application/x-www-form-urlencoded",
470            ContentType::Json => "application/json",
471            ContentType::Xml => "application/xml",
472            ContentType::Javascript => "application/javascript",
473            ContentType::Text => "text/plain",
474            ContentType::Html => "text/html",
475            ContentType::Other(name) => name.as_str(),
476            ContentType::Stream => "application/octet-stream"
477        }
478    }
479}
480
481/// 解析 `Content-Type` 请求头值,提取主 MIME 类型与参数(如 charset/boundary)。
482///
483/// - 输入示例:`application/json;charset=utf-8`、`application/json; charset=utf-8`
484/// - 输入示例:`multipart/form-data;boundary=abc`、`multipart/form-data; boundary="abc"`
485///
486/// 返回:
487/// - `mime`:主类型(已 `trim` 并 `to_lowercase`)
488/// - `params`:参数表(key 已 `to_lowercase`;value 已 `trim` 并去除可选引号)
489pub(crate) fn parse_content_type_header_value(
490    value: &str,
491) -> (String, std::collections::HashMap<String, String>) {
492    let mut it = value.split(';');
493    let mime = it.next().unwrap_or("").trim().to_lowercase();
494
495    let mut params = std::collections::HashMap::<String, String>::new();
496    for raw in it {
497        let raw = raw.trim();
498        if raw.is_empty() {
499            continue;
500        }
501        if let Some((k, v)) = raw.split_once('=') {
502            let key = k.trim().to_lowercase();
503            let mut val = v.trim();
504            if val.len() >= 2 && val.starts_with('"') && val.ends_with('"') {
505                val = &val[1..val.len() - 1];
506            }
507            params.insert(key, val.to_string());
508        } else {
509            // 允许无值参数(极少见),保留空字符串
510            params.insert(raw.to_lowercase(), String::new());
511        }
512    }
513
514    (mime, params)
515}
516/// 认证
517#[derive(Clone, Debug)]
518pub enum Authorization {
519    Basic(String, String),
520    Bearer(String),
521    Digest(JsonValue),
522    Other(String),
523}
524impl Authorization {
525    #[must_use]
526    pub fn from(data: &str) -> Self {
527        let authorization = data.split_whitespace().collect::<Vec<&str>>();
528        let mode = authorization[0].to_lowercase();
529        match mode.as_str() {
530            "basic" => {
531                let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
532                let text: Vec<&str> = text.split(':').collect();
533                Self::Basic(text[0].to_string(), text[1].to_string())
534            }
535            "bearer" => Self::Bearer(authorization[1].to_string()),
536            "digest" => {
537                let text = authorization[1..].concat().clone();
538                let text = text.split(',').collect::<Vec<&str>>();
539                let mut params = object! {};
540                for item in &text {
541                    let Some(index) = item.find('=') else { continue };
542                    let key = item[..index].to_string();
543                    let value = item[index + 2..item.len() - 1].to_string();
544                    let _ = params.insert(key.as_str(), value);
545                }
546                Self::Digest(params)
547            }
548            _ => Self::Other(data.to_string())
549        }
550    }
551    pub fn str(&mut self) -> JsonValue {
552        match self {
553            Authorization::Basic(key, value) => {
554                let mut data = object! {};
555                data[key.as_str()] = value.clone().into();
556                data
557            }
558            Authorization::Bearer(e) => e.clone().into(),
559            Authorization::Digest(e) => e.clone(),
560            Authorization::Other(name) => name.clone().into(),
561        }
562    }
563}
564/// 消息内容
565#[derive(Clone, Debug)]
566pub enum Content {
567    FormUrlencoded(JsonValue),
568    FormData(JsonValue),
569    Json(JsonValue),
570    Text(JsonValue),
571    Xml(JsonValue),
572    None,
573}
574impl Content {}
575#[derive(Clone, Debug)]
576pub enum FormData {
577    File(String, PathBuf),
578    Field(JsonValue),
579}
580
581/// 语言
582#[derive(Clone, Debug)]
583pub enum Language {
584    ZhCN,
585    ZhHans,
586    En,
587    Other(String),
588
589}
590impl Language {
591    #[must_use]
592    pub fn from(name: &str) -> Self {
593        let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
594        let name = binding.as_str();
595        match name {
596            "zh-cn" => Self::ZhCN,
597            "zh-hans" => Self::ZhHans,
598            "en" => Self::En,
599            _ => Self::Other(name.to_string()),
600        }
601    }
602    #[must_use]
603    pub fn str(&self) -> &str {
604        match self {
605            Language::ZhCN => "zh-CN",
606            Language::ZhHans => "zh-Hans",
607            Language::En => "en",
608            Language::Other(e) => e.as_str(),
609        }
610    }
611}
612
613
614/// 压缩方式
615#[derive(Clone, Debug)]
616pub enum Encoding {
617    Gzip,
618    Deflate,
619    Br,
620    Bzip2,
621    None,
622}
623impl Encoding {
624    #[must_use]
625    pub fn from(s: &str) -> Encoding {
626        match s.to_lowercase().as_str() {
627            x if x.contains("gzip") => Encoding::Gzip,
628            x if x.contains("deflate") => Encoding::Deflate,
629            x if x.contains("br") => Encoding::Br,
630            x if x.contains("bzip2") => Encoding::Bzip2,
631            _ => Encoding::None,
632        }
633    }
634    #[must_use]
635    pub fn str(&self) -> &str {
636        match self {
637            Encoding::Gzip => "gzip",
638            Encoding::Deflate => "deflate",
639            Encoding::Br => "br",
640            Encoding::Bzip2 => "bzip2",
641            Encoding::None => "",
642        }
643    }
644    /// 压缩
645    pub fn compress(&mut self, data: &[u8]) -> Result<Vec<u8>, String> {
646        match self {
647            Encoding::Gzip => {
648                let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
649                match encoder.write_all(data) {
650                    Ok(()) => {}
651                    Err(e) => {
652                        return Err(format!("Failed to compress file {}", e));
653                    }
654                };
655                match encoder.finish() {
656                    Ok(e) => Ok(e),
657                    Err(e) => Err(format!("Failed to compress file {}", e))
658                }
659            }
660            _ => Ok(data.to_vec()),
661        }
662    }
663    /// 解压
664    pub fn decompress(&mut self, data: &[u8]) -> Result<Vec<u8>, String> {
665        match self {
666            Encoding::Gzip => {
667                let mut d = GzDecoder::new(data);
668                let mut s = String::new();
669                match d.read_to_string(&mut s) {
670                    Ok(_) => {}
671                    Err(e) => {
672                        return Err(format!("Failed to decompress file {}", e));
673                    }
674                };
675                Ok(s.as_bytes().to_vec())
676            }
677            Encoding::Br => {
678                let mut decompressed = Vec::new();
679                let mut reader = brotli::Decompressor::new(data, 4096);
680                reader.read_to_end(&mut decompressed).map_err(|e| format!("brotli decompress error: {e}"))?;
681                Ok(decompressed)
682            }
683            _ => Ok(data.to_vec()),
684        }
685    }
686}
687
688/// HTTP协议版本
689#[derive(Clone, Debug)]
690pub enum Protocol {
691    HTTP1_0,
692    HTTP1_1,
693    HTTP2,
694    HTTP3,
695    Other(String),
696}
697
698impl Protocol {
699    pub fn from(name: &str) -> Self {
700        match name.to_lowercase().as_str() {
701            "http/1.0" => Protocol::HTTP1_0,
702            "http/1.1" => Protocol::HTTP1_1,
703            "http/2.0" | "http/2" => Protocol::HTTP2,
704            "http/3.0" | "http/3" => Protocol::HTTP3,
705            _ => Protocol::Other(name.to_lowercase())
706        }
707    }
708    pub fn str(&self) -> &str {
709        match self {
710            Protocol::HTTP1_0 => "HTTP/1.0",
711            Protocol::HTTP1_1 => "HTTP/1.1",
712            Protocol::HTTP2 => "HTTP/2.0",
713            Protocol::HTTP3 => "HTTP/3.0",
714            Protocol::Other(protocol) => protocol.as_str(),
715        }
716    }
717}
718/// 响应状态
719#[derive(Clone, Debug)]
720pub struct Status {
721    pub code: u16,
722    reason: String,
723}
724impl Status {
725    pub fn set_code(&mut self, code: u16) {
726        self.code = code;
727        self.reason = match code {
728            100 => "Continue", // 服务器愿意接收请求实体(配合 Expect: 100-continue)。
729            101 => "Switching Protocols", // 协议切换(如升级到 WebSocket)。
730            102 => "Processing",
731            103 => "Early Hints", // 提前提示可预加载的资源。
732            200 => "OK", // 请求成功(GET/PUT/PATCH 通用)
733            201 => "Created", // 已创建新资源(典型于 POST)
734            202 => "Accepted", // 已接受处理但未完成(异步任务)。
735            204 => "No Content", // 成功但无响应体(DELETE 常用)。
736            206 => "Partial Content", // 部分内容(Range 下载)。
737            301 => "Moved Permanently", // 永久重定向
738            302 => "Found", // 临时重定向(历史上易与 303/307混用)。
739            303 => "See Other", // 告诉客户端去 GET 另一个 URI(表单提交后跳详情页)。
740            304 => "Not Modified", // 资源未变更(配合缓存 ETag/Last-Modified)。
741            307 => "Temporary Redirect", // 临时,不改变方法(POST 仍是 POST)
742            308 => "Permanent Redirect", // 永久,不改变方法。
743
744            400 => "Bad Request", // 请求报文有误/语法错误/JSON 无法解析/缺少必需字段或头。
745            401 => "Unauthorized", // 未认证或凭证无效(要带 WWW-Authenticate)。
746            403 => "Forbidden",
747            404 => "Not Found", //服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
748            405 => "Method Not Allowed", // 方法不被允许(应返回 Allow 头)。
749            411 => "Length Required", // 缺少 Content-Length。
750            413 => "Payload Too Large", // 请求体过大。
751            414 => "URI Too Long", // URI 太长。
752            416 => "Range Not Satisfiable",
753            429 => "Too Many Requests", // 限流
754            431 => "Request Header Fields Too Large", // 请求头过大。
755
756            500 => "Internal Server Error", //服务器内部错误,无法完成请求
757            501 => "Not Implemented", //服务器不支持请求的功能,无法完成请求
758            502 => "Bad Gateway", //作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
759            503 => "Service Unavailable", //服务不可用/维护中(可带 Retry-After)。
760            504 => "Gateway Time-out",    //网关超时(上游响应超时)。
761            505 => "HTTP Version Not Supported", //服务器不支持请求的HTTP协议的版本,无法完成处理
762            _ => "",
763        }.to_string();
764    }
765    pub fn from(code: u16, reason: &str) -> Self {
766        Status {
767            code,
768            reason: reason.to_string(),
769        }
770    }
771}
772impl Default for Status {
773    fn default() -> Self {
774        Self {
775            code: 200,
776            reason: "OK".to_string(),
777        }
778    }
779}
780
781#[derive(Debug)]
782pub enum TransferEncoding {
783    Chunked,
784    Other(String),
785}
786impl TransferEncoding {
787    pub fn from(name: &str) -> TransferEncoding {
788        match name.to_lowercase().as_str() {
789            "chunked" => TransferEncoding::Chunked,
790            _ => TransferEncoding::Other(name.to_string()),
791        }
792    }
793}
794
795pub fn split_boundary(mut data: Vec<u8>, boundary: &str) -> Result<Vec<Vec<u8>>, String> {
796    let boundary = format!("--{boundary}");
797    let mut list = vec![];
798    loop {
799        if let Some(n) = data.to_vec().windows(boundary.len()).position(|x| x == boundary.as_bytes()) {
800            data.drain(n..boundary.len());
801            if data.is_empty() || data == "--\r\n".as_bytes().to_vec() {
802                break;
803            }
804        } else {
805            return Err("格式错误1".to_string());
806        }
807        if let Some(n) = data.to_vec().windows(boundary.len()).position(|x| x == boundary.as_bytes()) {
808            list.push(data[..n].to_vec());
809            data.drain(..n);
810        } else {
811            return Err("格式错误2".to_string());
812        }
813    }
814    Ok(list)
815}