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#[derive(Clone, Debug)]
482pub enum Authorization {
483    Basic(String, String),
484    Bearer(String),
485    Digest(JsonValue),
486    Other(String),
487}
488impl Authorization {
489    #[must_use]
490    pub fn from(data: &str) -> Self {
491        let authorization = data.split_whitespace().collect::<Vec<&str>>();
492        let mode = authorization[0].to_lowercase();
493        match mode.as_str() {
494            "basic" => {
495                let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
496                let text: Vec<&str> = text.split(':').collect();
497                Self::Basic(text[0].to_string(), text[1].to_string())
498            }
499            "bearer" => Self::Bearer(authorization[1].to_string()),
500            "digest" => {
501                let text = authorization[1..].concat().clone();
502                let text = text.split(',').collect::<Vec<&str>>();
503                let mut params = object! {};
504                for item in &text {
505                    let Some(index) = item.find('=') else { continue };
506                    let key = item[..index].to_string();
507                    let value = item[index + 2..item.len() - 1].to_string();
508                    let _ = params.insert(key.as_str(), value);
509                }
510                Self::Digest(params)
511            }
512            _ => Self::Other(data.to_string())
513        }
514    }
515    pub fn str(&mut self) -> JsonValue {
516        match self {
517            Authorization::Basic(key, value) => {
518                let mut data = object! {};
519                data[key.as_str()] = value.clone().into();
520                data
521            }
522            Authorization::Bearer(e) => e.clone().into(),
523            Authorization::Digest(e) => e.clone(),
524            Authorization::Other(name) => name.clone().into(),
525        }
526    }
527}
528/// 消息内容
529#[derive(Clone, Debug)]
530pub enum Content {
531    FormUrlencoded(JsonValue),
532    FormData(JsonValue),
533    Json(JsonValue),
534    Text(JsonValue),
535    Xml(JsonValue),
536    None,
537}
538impl Content {}
539#[derive(Clone, Debug)]
540pub enum FormData {
541    File(String, PathBuf),
542    Field(JsonValue),
543}
544
545/// 语言
546#[derive(Clone, Debug)]
547pub enum Language {
548    ZhCN,
549    ZhHans,
550    En,
551    Other(String),
552
553}
554impl Language {
555    #[must_use]
556    pub fn from(name: &str) -> Self {
557        let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
558        let name = binding.as_str();
559        match name {
560            "zh-cn" => Self::ZhCN,
561            "zh-hans" => Self::ZhHans,
562            "en" => Self::En,
563            _ => Self::Other(name.to_string()),
564        }
565    }
566    #[must_use]
567    pub fn str(&self) -> &str {
568        match self {
569            Language::ZhCN => "zh-CN",
570            Language::ZhHans => "zh-Hans",
571            Language::En => "en",
572            Language::Other(e) => e.as_str(),
573        }
574    }
575}
576
577
578/// 压缩方式
579#[derive(Clone, Debug)]
580pub enum Encoding {
581    Gzip,
582    Deflate,
583    Br,
584    Bzip2,
585    None,
586}
587impl Encoding {
588    #[must_use]
589    pub fn from(s: &str) -> Encoding {
590        match s.to_lowercase().as_str() {
591            x if x.contains("gzip") => Encoding::Gzip,
592            x if x.contains("deflate") => Encoding::Deflate,
593            x if x.contains("br") => Encoding::Br,
594            x if x.contains("bzip2") => Encoding::Bzip2,
595            _ => Encoding::None,
596        }
597    }
598    #[must_use]
599    pub fn str(&self) -> &str {
600        match self {
601            Encoding::Gzip => "gzip",
602            Encoding::Deflate => "deflate",
603            Encoding::Br => "br",
604            Encoding::Bzip2 => "bzip2",
605            Encoding::None => "",
606        }
607    }
608    /// 压缩
609    pub fn compress(&mut self, data: &[u8]) -> Result<Vec<u8>, String> {
610        match self {
611            Encoding::Gzip => {
612                let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
613                match encoder.write_all(data) {
614                    Ok(()) => {}
615                    Err(e) => {
616                        return Err(format!("Failed to compress file {}", e));
617                    }
618                };
619                match encoder.finish() {
620                    Ok(e) => Ok(e),
621                    Err(e) => Err(format!("Failed to compress file {}", e))
622                }
623            }
624            _ => Ok(data.to_vec()),
625        }
626    }
627    /// 解压
628    pub fn decompress(&mut self, data: &[u8]) -> Result<Vec<u8>, String> {
629        match self {
630            Encoding::Gzip => {
631                let mut d = GzDecoder::new(data);
632                let mut s = String::new();
633                match d.read_to_string(&mut s) {
634                    Ok(_) => {}
635                    Err(e) => {
636                        return Err(format!("Failed to decompress file {}", e));
637                    }
638                };
639                Ok(s.as_bytes().to_vec())
640            }
641            _ => Ok(data.to_vec()),
642        }
643    }
644}
645
646/// HTTP协议版本
647#[derive(Clone, Debug)]
648pub enum Protocol {
649    HTTP1_0,
650    HTTP1_1,
651    HTTP2,
652    HTTP3,
653    Other(String),
654}
655
656impl Protocol {
657    pub fn from(name: &str) -> Self {
658        match name.to_lowercase().as_str() {
659            "http/1.0" => Protocol::HTTP1_0,
660            "http/1.1" => Protocol::HTTP1_1,
661            "http/2.0" | "http/2" => Protocol::HTTP2,
662            "http/3.0" | "http/3" => Protocol::HTTP3,
663            _ => Protocol::Other(name.to_lowercase())
664        }
665    }
666    pub fn str(&self) -> &str {
667        match self {
668            Protocol::HTTP1_0 => "HTTP/1.0",
669            Protocol::HTTP1_1 => "HTTP/1.1",
670            Protocol::HTTP2 => "HTTP/2.0",
671            Protocol::HTTP3 => "HTTP/3.0",
672            Protocol::Other(protocol) => protocol.as_str(),
673        }
674    }
675}
676/// 响应状态
677#[derive(Clone, Debug)]
678pub struct Status {
679    pub code: u16,
680    reason: String,
681}
682impl Status {
683    pub fn set_code(&mut self, code: u16) {
684        self.code = code;
685        self.reason = match code {
686            100 => "Continue", // 服务器愿意接收请求实体(配合 Expect: 100-continue)。
687            101 => "Switching Protocols", // 协议切换(如升级到 WebSocket)。
688            102 => "Processing",
689            103 => "Early Hints", // 提前提示可预加载的资源。
690            200 => "OK", // 请求成功(GET/PUT/PATCH 通用)
691            201 => "Created", // 已创建新资源(典型于 POST)
692            202 => "Accepted", // 已接受处理但未完成(异步任务)。
693            204 => "No Content", // 成功但无响应体(DELETE 常用)。
694            206 => "Partial Content", // 部分内容(Range 下载)。
695            301 => "Moved Permanently", // 永久重定向
696            302 => "Found", // 临时重定向(历史上易与 303/307混用)。
697            303 => "See Other", // 告诉客户端去 GET 另一个 URI(表单提交后跳详情页)。
698            304 => "Not Modified", // 资源未变更(配合缓存 ETag/Last-Modified)。
699            307 => "Temporary Redirect", // 临时,不改变方法(POST 仍是 POST)
700            308 => "Permanent Redirect", // 永久,不改变方法。
701
702            400 => "Bad Request", // 请求报文有误/语法错误/JSON 无法解析/缺少必需字段或头。
703            401 => "Unauthorized", // 未认证或凭证无效(要带 WWW-Authenticate)。
704            403 => "Forbidden",
705            404 => "Not Found", //服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
706            405 => "Method Not Allowed", // 方法不被允许(应返回 Allow 头)。
707            411 => "Length Required", // 缺少 Content-Length。
708            413 => "Payload Too Large", // 请求体过大。
709            414 => "URI Too Long", // URI 太长。
710            416 => "Range Not Satisfiable",
711            429 => "Too Many Requests", // 限流
712            431 => "Request Header Fields Too Large", // 请求头过大。
713
714            500 => "Internal Server Error", //服务器内部错误,无法完成请求
715            501 => "Not Implemented", //服务器不支持请求的功能,无法完成请求
716            502 => "Bad Gateway", //作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
717            503 => "Service Unavailable", //服务不可用/维护中(可带 Retry-After)。
718            504 => "Gateway Time-out",    //网关超时(上游响应超时)。
719            505 => "HTTP Version Not Supported", //服务器不支持请求的HTTP协议的版本,无法完成处理
720            _ => "",
721        }.to_string();
722    }
723    pub fn from(code: u16, reason: &str) -> Self {
724        Status {
725            code,
726            reason: reason.to_string(),
727        }
728    }
729}
730impl Default for Status {
731    fn default() -> Self {
732        Self {
733            code: 200,
734            reason: "OK".to_string(),
735        }
736    }
737}
738
739#[derive(Debug)]
740pub enum TransferEncoding {
741    Chunked,
742    Other(String),
743}
744impl TransferEncoding {
745    pub fn from(name: &str) -> TransferEncoding {
746        match name.to_lowercase().as_str() {
747            "chunked" => TransferEncoding::Chunked,
748            _ => TransferEncoding::Other(name.to_string()),
749        }
750    }
751}
752
753pub fn split_boundary(mut data: Vec<u8>, boundary: &str) -> Result<Vec<Vec<u8>>, String> {
754    let boundary = format!("--{boundary}");
755    let mut list = vec![];
756    loop {
757        if let Some(n) = data.to_vec().windows(boundary.len()).position(|x| x == boundary.as_bytes()) {
758            data.drain(n..boundary.len());
759            if data.is_empty() || data == "--\r\n".as_bytes().to_vec() {
760                break;
761            }
762        } else {
763            return Err("格式错误1".to_string());
764        }
765        if let Some(n) = data.to_vec().windows(boundary.len()).position(|x| x == boundary.as_bytes()) {
766            list.push(data[..n].to_vec());
767            data.drain(..n);
768        } else {
769            return Err("格式错误2".to_string());
770        }
771    }
772    Ok(list)
773}