Skip to main content

br_web_server/
lib.rs

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