br_web_server/
request.rs

1use crate::config::{Config};
2use crate::encoding::Encoding;
3use chrono::{DateTime, Local};
4use json::{array, object, JsonValue};
5use log::{error, info, warn};
6use std::io::{Error, Write};
7use std::path::{Path, PathBuf};
8use std::{env, fs, io, thread};
9use std::fs::OpenOptions;
10use std::sync::{Arc, Mutex};
11use std::time::Instant;
12use crate::stream::{Protocol, Scheme};
13
14/// 请求体
15#[derive(Clone, Debug)]
16pub struct Request {
17    pub config: Config,
18    /// 协议版本
19    pub protocol: Protocol,
20    /// 当前请求类型
21    pub method: Method,
22    /// 资源标识符
23    pub uri: Uri,
24    /// header信息
25    pub header: JsonValue,
26    /// Cookie信息
27    pub cookie: JsonValue,
28    /// 请求体
29    pub body: Body,
30    /// 认证信息
31    pub authorization: Authorization,
32    /// 处理耗时
33    pub handle_time: String,
34    /// 请求时间
35    pub datetime: String,
36    /// 请求时间戳
37    pub timestamp: i64,
38    /// 客户端IP
39    pub client_ip: String,
40    /// 代理端IP
41    pub proxy_ip: String,
42    /// 服务端IP
43    pub server_ip: String,
44    /// 升级协议
45    pub upgrade: Upgrade,
46    /// 连接的持久性
47    pub connection: Connection,
48    /// 编码
49    pub accept_encoding: Encoding,
50    /// 开始时间
51    start_time: Instant,
52    /// 原始请求数据
53    pub raw_data: Vec<u8>,
54    /// 请求头数据
55    pub header_data: Vec<u8>,
56    /// 请求体数据
57    pub body_data: Vec<u8>,
58    pub scheme: Arc<Mutex<Scheme>>,
59}
60impl Request {
61    #[must_use]
62    pub fn default(config: Config, scheme: Arc<Mutex<Scheme>>) -> Self {
63
64        // 获取请求客户端IP
65        let client_ip = scheme.lock().unwrap().client_ip();
66        // 获取服务端IP
67        let server_ip = scheme.lock().unwrap().server_ip();
68        let local: DateTime<Local> = Local::now();
69        Self {
70            config,
71            protocol: Protocol::None,
72            method: Method::None,
73            uri: Uri::default(),
74            header: object! {},
75            cookie: object! {},
76            body: Body::default(),
77            authorization: Authorization::None,
78            handle_time: String::new(),
79            scheme,
80            start_time: Instant::now(),
81            datetime: local.format("%Y-%m-%d %H:%M:%S").to_string(),
82            timestamp: local.timestamp(),
83            client_ip,
84            server_ip,
85            proxy_ip: String::new(),
86            upgrade: Upgrade::Http,
87            connection: Connection::None,
88            accept_encoding: Encoding::None,
89            raw_data: vec![],
90            header_data: vec![],
91            body_data: vec![],
92        }
93    }
94
95    pub fn handle(&mut self) -> io::Result<()> {
96        // 头部处理
97        loop {
98            let data = self.scheme.lock().unwrap().read()?;
99            self.raw_data.extend(data);
100            if let Some(pos) = self.raw_data.windows(4).position(|window| window == [13, 10, 13, 10]) {
101                self.header_data = self.raw_data[..pos].to_vec();
102                self.body_data.extend(self.raw_data[pos + 4..].to_vec());
103                break;
104            }
105        }
106        self.handle_header()?;
107        if self.body.content_length > 0 {
108            loop {
109                if self.body_data.len() == self.body.content_length {
110                    break;
111                }
112                let data = self.scheme.lock().unwrap().read()?;
113                self.raw_data.extend(data.clone());
114                self.body_data.extend(data);
115            }
116            self.body.set_content(self.body_data.clone());
117        }
118        self.handle_time = format!("{:?}", self.start_time.elapsed());
119        Ok(())
120    }
121    pub fn handle_header(&mut self) -> io::Result<()> {
122        if self.config.debug {
123            let text = unsafe { String::from_utf8_unchecked(self.header_data.clone()) };
124            info!("\r\n=================请求信息 {:?}=================\r\n{text}\r\n========================================",thread::current().id());
125        }
126        let headers = String::from_utf8_lossy(self.header_data.as_slice());
127        let line = headers.lines().next().unwrap_or("");
128        let lines = line.split_whitespace().collect::<Vec<&str>>();
129        if lines.len() != 3 {
130            return Err(Error::other("请求行错误"));
131        }
132        self.protocol = Protocol::from(lines[2]);
133        match self.protocol {
134            Protocol::HTTP1_0 | Protocol::HTTP1_1 => {
135                self.method = Method::from(lines[0]);
136                self.uri = Uri::from(lines[1]);
137                for item in headers.lines().skip(1) {
138                    match item.trim().find(':') {
139                        None => continue,
140                        Some(e) => {
141                            let key = item[..e].trim().to_lowercase().clone();
142                            let value = item[e + 1..].trim().to_string();
143                            self.header[key] = value.into();
144                        }
145                    };
146                }
147            }
148            Protocol::HTTP2 => {
149                let res = self.header_data[..8].to_vec();
150                if !res.eq(b"\r\nSM\r\n\r\n") {
151                    return Err(Error::other("HTTP2格式错误"));
152                }
153            }
154            Protocol::None => {
155                return Err(Error::other("格式错误"));
156            }
157        }
158        if self.header.has_key("content-length") {
159            self.body.content_length = self.header["content-length"].to_string().parse::<usize>().unwrap_or(0);
160        }
161        if self.header.has_key("content-type") {
162            let t = self.header["content-type"].as_str().unwrap().split_whitespace().collect::<Vec<&str>>();
163            match t[0] {
164                _ if t[0].contains("multipart/form-data") => {
165                    self.body.boundary = t[1].trim().trim_start_matches("boundary=").to_string();
166                    self.body.content_type = ContentType::from("multipart/form-data");
167                }
168                _ => {
169                    self.body.content_type = ContentType::from(t[0]);
170                }
171            }
172            let _ = self.header.insert("content-type", self.body.content_type.str());
173        }
174        if self.header.has_key("authorization") {
175            self.authorization = Authorization::from(self.header["authorization"].as_str().unwrap_or(""));
176        }
177
178        if self.header.has_key("upgrade") {
179            self.upgrade = Upgrade::from(self.header["upgrade"].as_str().unwrap_or(""));
180        }
181        if self.header.has_key("connection") {
182            self.connection = Connection::from(self.header["connection"].as_str().unwrap_or(""));
183        }
184        if self.header.has_key("accept-encoding") {
185            self.accept_encoding = Encoding::from(self.header["accept-encoding"].as_str().unwrap_or(""));
186        }
187        if self.header.has_key("cookie") {
188            let _ = self.header["cookie"].to_string().split(';').collect::<Vec<&str>>().iter().map(|&x| {
189                match x.find('=') {
190                    None => {}
191                    Some(index) => {
192                        let key = x[..index].trim().to_string();
193                        let val = x[index + 1..].trim().to_string();
194                        let _ = self.cookie.insert(key.as_str(), val);
195                    }
196                }
197                ""
198            }).collect::<Vec<&str>>();
199        }
200        if self.header.has_key("x-forwarded-for") {
201            self.proxy_ip = self.header["x-forwarded-for"].as_str().unwrap_or("").to_string();
202        }
203        if self.header.has_key("x-real-ip") {
204            self.client_ip = self.header["x-real-ip"].as_str().unwrap_or("").to_string();
205        }
206        self.uri.handle(self.header["host"].as_str().unwrap_or(""));
207        self.uri.scheme = if self.config.https { "https" } else { "http" }.to_string();
208        Ok(())
209    }
210
211    pub fn set_http2_headers(&mut self, key: &str, value: &str) {
212        match key {
213            "content-type" => match value {
214                _ if value.contains("multipart/form-data") => {
215                    let boundarys = value.split("boundary=").collect::<Vec<&str>>();
216                    self.body.boundary = boundarys[1..].join("");
217                    self.body.content_type = ContentType::from("multipart/form-data");
218                    self.header.insert(key, "multipart/form-data").unwrap();
219                }
220                _ => {
221                    let value = match value.find(';') {
222                        None => value,
223                        Some(e) => &*value[..e].trim().to_string(),
224                    };
225                    self.body.content_type = ContentType::from(value);
226                    let _ = self.header.insert(key, self.body.content_type.str());
227                }
228            },
229            "content-length" => {
230                self.body.content_length = value.to_string().parse::<usize>().unwrap_or(0);
231            }
232            "authorization" => {
233                self.authorization = Authorization::from(value);
234            }
235            "cookie" => {
236                let _ = value.split(';').collect::<Vec<&str>>().iter().map(|&x| {
237                    match x.find('=') {
238                        None => {}
239                        Some(index) => {
240                            let key = x[..index].trim().to_string();
241                            let val = x[index + 1..].trim().to_string();
242                            let _ = self.cookie.insert(key.as_str(), val);
243                        }
244                    }
245                    ""
246                }).collect::<Vec<&str>>();
247            }
248            "upgrade" => {
249                self.upgrade = Upgrade::from(value);
250            }
251            "connection" => {
252                self.connection = Connection::from(value);
253            }
254            "accept-encoding" => {
255                self.accept_encoding = Encoding::from(value);
256            }
257            _ => {
258                self.header.insert(key, value).unwrap();
259            }
260        }
261    }
262
263    /// 保存日志
264    pub fn save_log(&mut self) -> io::Result<()> {
265        if !self.config.log {
266            return Ok(());
267        }
268        let local: DateTime<Local> = Local::now();
269        let time_dir = local.format("%Y-%m-%d-%H").to_string();
270        let time_dir = time_dir.split('-').collect::<Vec<&str>>();
271
272        let mut res = self.config.root_path.join(self.config.runtime.clone()).join("log");
273        for item in &time_dir {
274            res.push(item);
275        }
276        fs::create_dir_all(res.parent().unwrap())?;
277        let log_file = format!("{}.log", res.to_str().unwrap());
278        let mut file = OpenOptions::new()
279            // 允许写入
280            .append(true) // 追加内容到文件末尾
281            .create(true) // 如果文件不存在,则创建
282            .open(log_file)?;
283        let data = format!(
284            "[{}] {} ClientIP: {} {} {} ContentLength: {} ContentType: {} Time: {:?}\r\n",
285            self.datetime,
286            self.protocol.str(),
287            self.client_ip,
288            self.method.str(),
289            self.uri.url,
290            self.body.content_length,
291            self.body.content_type.str(),
292            self.handle_time
293        );
294        file.write_all(data.as_bytes())?;
295        Ok(())
296    }
297    /// 读取资源文件
298    pub fn read_resource(&mut self) -> io::Result<PathBuf> {
299        if self.uri.path != "/" {
300            let file = self.config.root_path.join(self.config.public.clone()).join(self.uri.path.trim_start_matches('/'));
301            if file.is_file() {
302                return Ok(file);
303            }
304        }
305        if let Method::GET = self.method {
306            if self.uri.path == "/" {
307                let file = self.config.root_path.join("webpage").join(self.config.webpage.clone()).join("index.html");
308                if file.is_file() {
309                    return Ok(file);
310                }
311            } else {
312                let file = self.config.root_path.join("webpage").join(self.config.webpage.clone()).join(self.uri.path.trim_start_matches('/'));
313                if file.is_file() {
314                    return Ok(file);
315                }
316            }
317        }
318        Err(Error::other("Not a file"))
319    }
320}
321
322
323/// 请求方法
324#[derive(Clone, Debug)]
325pub enum Method {
326    POST,
327    GET,
328    HEAD,
329    PUT,
330    DELETE,
331    OPTIONS,
332    PATCH,
333    TRACE,
334    VIEW,
335    PROPFIND,
336    /// http2.0
337    PRI,
338    None,
339}
340
341impl Method {
342    #[must_use]
343    pub fn from(name: &str) -> Self {
344        match name.to_lowercase().as_str() {
345            "post" => Self::POST,
346            "get" => Self::GET,
347            "head" => Self::HEAD,
348            "put" => Self::PUT,
349            "delete" => Self::DELETE,
350            "options" => Self::OPTIONS,
351            "patch" => Self::PATCH,
352            "trace" => Self::TRACE,
353            "view" => Self::VIEW,
354            "propfind" => Self::PROPFIND,
355            "pri" => Self::PRI,
356            _ => Self::None,
357        }
358    }
359    pub fn str(&mut self) -> &str {
360        match self {
361            Method::POST => "POST",
362            Method::GET => "GET",
363            Method::HEAD => "HEAD",
364            Method::PUT => "PUT",
365            Method::DELETE => "DELETE",
366            Method::OPTIONS => "OPTIONS",
367            Method::PATCH => "PATCH",
368            Method::TRACE => "TRACE",
369            Method::VIEW => "VIEW",
370            Method::PROPFIND => "PROPFIND",
371            Method::PRI => "PRI",
372            Method::None => "",
373        }
374    }
375}
376/// 统一资源标识符
377#[derive(Clone, Debug)]
378pub struct Uri {
379    /// 完整 url
380    pub url: String,
381    /// 查询字符串
382    pub query: String,
383    /// 查询参数
384    pub query_params: JsonValue,
385    /// 片段或位置
386    pub fragment: String,
387    /// 资源路径
388    pub path: String,
389    /// 资源段落
390    pub path_segments: Vec<String>,
391    /// 访问协议
392    pub scheme: String,
393    /// 主机名或 IP 地址
394    pub host: String,
395    /// 端口号
396    pub port: String,
397}
398impl Uri {
399    #[must_use]
400    pub fn from(url: &str) -> Self {
401        let mut decoded_url = Uri::decode(url).unwrap_or(url.to_string());
402        let fragment = match decoded_url.rfind('#') {
403            None => String::new(),
404            Some(index) => decoded_url.drain(index..).collect::<String>(),
405        };
406        let mut query = String::new();
407        let query_params = match decoded_url.rfind('?') {
408            None => object! {},
409            Some(index) => {
410                let text = decoded_url.drain(index..).collect::<String>();
411                query = text.trim_start_matches('?').parse().unwrap();
412                let text = query.split('&').collect::<Vec<&str>>();
413                let mut params = object! {};
414                for &item in &text {
415                    if let Some(index) = item.find('=') {
416                        let key = item[..index].to_string();
417                        let value = item[index + 1..].to_string();
418                        let _ = params.insert(
419                            Uri::decode(&key).unwrap_or(key.to_string()).as_str(),
420                            Uri::decode(&value).unwrap_or(key.to_string()),
421                        );
422                    }
423                }
424                params
425            }
426        };
427        let path_segments = decoded_url.split('/').collect::<Vec<&str>>();
428        let path_segments = path_segments.into_iter().filter(|&x| !x.is_empty()).collect::<Vec<&str>>().iter().map(|&x| x.to_string()).collect::<Vec<String>>();
429        Self {
430            url: url.to_string(),
431            query,
432            query_params,
433            fragment,
434            path: decoded_url.clone(),
435            path_segments,
436            scheme: String::new(),
437            host: String::new(),
438            port: String::new(),
439        }
440    }
441    /// 解码
442    pub fn decode(input: &str) -> Result<String, String> {
443        let mut decoded = String::new();
444        let bytes = input.as_bytes();
445        let mut i = 0;
446
447        while i < bytes.len() {
448            if bytes[i] == b'%' {
449                if i + 2 >= bytes.len() {
450                    return Err("Incomplete percent-encoding".into());
451                }
452                let hex = &input[i + 1..i + 3];
453                match u8::from_str_radix(hex, 16) {
454                    Ok(byte) => decoded.push(byte as char),
455                    Err(_) => return Err(format!("Invalid percent-encoding: %{hex}")),
456                }
457                i += 3;
458            } else if bytes[i] == b'+' {
459                decoded.push(' ');
460                i += 1;
461            } else {
462                decoded.push(bytes[i] as char);
463                i += 1;
464            }
465        }
466
467        Ok(decoded)
468    }
469    pub fn handle(&mut self, host: &str) {
470        if !host.is_empty() {
471            let hostport = host.split(':').collect::<Vec<&str>>();
472            if hostport.len() > 1 {
473                self.host = hostport[0].to_string();
474                self.port = hostport[1].to_string();
475            } else {
476                self.host = hostport[0].to_string();
477            }
478        }
479    }
480    #[must_use]
481    pub fn to_json(&self) -> JsonValue {
482        object! {
483            url: self.url.clone(),
484            query: self.query.clone(),
485            query_params: self.query_params.clone(),
486            fragment: self.fragment.clone(),
487            path: self.path.clone(),
488            path_segments: self.path_segments.clone(),
489            scheme: self.scheme.clone(),
490            host: self.host.clone(),
491            port: self.port.clone(),
492        }
493    }
494}
495
496impl Default for Uri {
497    fn default() -> Self {
498        Self {
499            url: String::new(),
500            query: String::new(),
501            query_params: object! {},
502            fragment: String::new(),
503            path: String::new(),
504            scheme: String::new(),
505            path_segments: Vec::new(),
506            host: String::new(),
507            port: String::new(),
508        }
509    }
510}
511
512/// 内容类型
513#[derive(Debug, Clone)]
514pub enum ContentType {
515    FormData,
516    FormUrlencoded,
517    Json,
518    Xml,
519    Javascript,
520    Text,
521    Html,
522    Other(String),
523}
524impl ContentType {
525    #[must_use]
526    pub fn from(name: &str) -> Self {
527        match name {
528            "multipart/form-data" => Self::FormData,
529            "application/x-www-form-urlencoded" => Self::FormUrlencoded,
530            "application/json" => Self::Json,
531            "application/xml" | "text/xml" => Self::Xml,
532            "application/javascript" => Self::Javascript,
533            "text/html" => Self::Html,
534            "text/plain" => Self::Text,
535            _ => Self::Other(name.to_string()),
536        }
537    }
538    pub fn str(&mut self) -> String {
539        match self {
540            Self::FormData => "multipart/form-data",
541            Self::FormUrlencoded => "application/x-www-form-urlencoded",
542            Self::Json => "application/json",
543            Self::Xml => "application/xml",
544            Self::Javascript => "application/javascript",
545            Self::Text => "text/plain",
546            Self::Html => "text/html",
547            Self::Other(name) => name,
548        }.to_string()
549    }
550}
551/// 认证
552#[derive(Clone, Debug)]
553pub enum Authorization {
554    Basic(String, String),
555    Bearer(String),
556    Digest(JsonValue),
557    None,
558}
559impl Authorization {
560    #[must_use]
561    pub fn from(data: &str) -> Self {
562        let authorization = data.split_whitespace().collect::<Vec<&str>>();
563        let mode = authorization[0].to_lowercase();
564        match mode.as_str() {
565            "basic" => {
566                let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
567                let text: Vec<&str> = text.split(':').collect();
568                Self::Basic(text[0].to_string(), text[1].to_string())
569            }
570            "bearer" => Self::Bearer(authorization[1].to_string()),
571            "digest" => {
572                let text = authorization[1..].concat().clone();
573                let text = text.split(',').collect::<Vec<&str>>();
574                let mut params = object! {};
575                for item in &text {
576                    let index = match item.find('=') {
577                        None => continue,
578                        Some(e) => e,
579                    };
580                    let key = item[..index].to_string();
581                    let value = item[index + 2..item.len() - 1].to_string();
582                    let _ = params.insert(key.as_str(), value);
583                }
584
585                Self::Digest(params)
586            }
587            _ => {
588                warn!("未知认证模式: {mode}");
589                Self::None
590            }
591        }
592    }
593    pub fn str(&mut self) -> JsonValue {
594        match self {
595            Authorization::Basic(key, value) => {
596                let mut data = object! {};
597                data[key.as_str()] = value.clone().into();
598                data
599            }
600            Authorization::Bearer(e) => e.clone().into(),
601            Authorization::Digest(e) => e.clone(),
602            Authorization::None => "".into(),
603        }
604    }
605}
606
607#[derive(Debug, Clone)]
608pub struct Body {
609    pub content_type: ContentType,
610    pub boundary: String,
611    pub content_length: usize,
612    pub content: JsonValue,
613}
614impl Body {
615    pub fn set_content(&mut self, data: Vec<u8>) {
616        if self.content_length == 0 {
617            return;
618        }
619        match self.content_type {
620            ContentType::FormData => {
621                let mut fields = object! {};
622                let boundary_marker = format!("--{}", self.boundary);
623
624
625                let parts = split_vec_u8(&data, boundary_marker.as_bytes());
626
627                for part in parts {
628                    if part.eq(b"\r\n") || part.is_empty() || part.eq(b"--") || part.eq(b"--\r\n") || part.eq(format!("--{}", self.boundary).as_bytes()) {
629                        continue; // 跳过无效部分
630                    }
631
632                    let headers_and_body = split_vec_u8(&part, b"\r\n\r\n");
633                    if headers_and_body.len() == 1 {
634                        let headers = unsafe { String::from_utf8_unchecked(headers_and_body[0].clone()) };
635                        error!(">>>>>>>>>>>>{headers:?}");
636                        continue;
637                    }
638
639                    let headers = unsafe { String::from_utf8_unchecked(headers_and_body[0].clone()) };
640                    let body = headers_and_body[1].clone();
641                    {
642                        // 解析头部,查找 Content-Disposition
643                        let headers = headers.split("\r\n");
644
645                        let mut field_name = "";
646                        let mut filename = "";
647                        let mut content_type = ContentType::Text;
648
649                        for header in headers {
650                            if header.to_lowercase().starts_with("content-disposition:") {
651                                match header.find("filename=\"") {
652                                    None => {}
653                                    Some(filename_start) => {
654                                        let filename_len = filename_start + 10;
655                                        let filename_end = header[filename_len..].find('"').unwrap() + filename_len;
656                                        filename = &header[filename_len..filename_end];
657                                    }
658                                }
659                                match header.find("name=\"") {
660                                    None => {}
661                                    Some(name_start) => {
662                                        let name_start = name_start + 6;
663                                        let name_end = header[name_start..].find('"').unwrap() + name_start;
664                                        field_name = &header[name_start..name_end];
665                                    }
666                                }
667                            }
668                            if header.to_lowercase().starts_with("content-type:") {
669                                content_type = ContentType::from(
670                                    header.to_lowercase().trim_start_matches("content-type:").trim(),
671                                );
672                            }
673                        }
674                        if filename.is_empty() {
675                            let text = String::from_utf8_lossy(&body);
676                            fields[field_name.to_string()] = JsonValue::from(text.lines().next().unwrap());
677                        } else {
678                            let extension = Path::new(filename).extension() // 可能返回 None
679                                                               .and_then(|ext| ext.to_str()); // 转换为 &str
680                            let suffix = extension.unwrap_or("txt");
681                            let filename = if extension.is_none() {
682                                format!("{filename}.txt")
683                            } else {
684                                filename.to_string()
685                            };
686                            // 获取系统临时目录
687                            let mut temp_dir = env::temp_dir();
688                            // 构造临时文件的完整路径
689                            temp_dir.push(filename.clone());
690                            // 打开(创建)临时文件
691                            let Ok(mut temp_file) = fs::File::create(&temp_dir) else { continue };
692
693                            if temp_file.write(body.as_slice()).is_ok() {
694                                if fields[field_name.to_string()].is_empty() {
695                                    fields[field_name.to_string()] = array![];
696                                }
697
698                                fields[field_name.to_string()].push(object! {
699                                        id:br_crypto::sha256::encrypt_hex(&body.clone()),
700                                        name:filename,
701                                        suffix:suffix,
702                                        size:body.len(),
703                                        type:content_type.str(),
704                                        file:temp_dir.to_str()
705                                    }).unwrap();
706                            }
707                        }
708                    }
709                }
710                self.content = fields;
711            }
712            ContentType::FormUrlencoded => {
713                let text = unsafe { String::from_utf8_unchecked(data) };
714                let params = text.split('&').collect::<Vec<&str>>();
715                let mut list = object! {};
716                for param in &params {
717                    let t = param.split('=').collect::<Vec<&str>>().iter().map(|&x| Uri::decode(x).unwrap_or(x.to_string())).collect::<Vec<String>>();
718                    list[t[0].to_string()] = t[1].clone().into();
719                }
720                self.content = list;
721            }
722            ContentType::Json => {
723                let text = unsafe { String::from_utf8_unchecked(data) };
724                self.content = json::parse(text.as_str()).unwrap_or(object! {});
725            }
726            ContentType::Xml | ContentType::Html | ContentType::Text | ContentType::Javascript | ContentType::Other(_) => {
727                let text = unsafe { String::from_utf8_unchecked(data) };
728                self.content = text.into();
729            }
730        }
731    }
732}
733fn split_vec_u8(data: &[u8], delimiter: &[u8]) -> Vec<Vec<u8>> {
734    let mut parts = Vec::new();
735    let mut start = 0;
736    let mut i = 0;
737
738    while i <= data.len().saturating_sub(delimiter.len()) {
739        if &data[i..i + delimiter.len()] == delimiter {
740            parts.push(data[start..i].to_vec());
741            i += delimiter.len();
742            start = i;
743        } else {
744            i += 1;
745        }
746    }
747
748    // 剩下的部分
749    if start <= data.len() {
750        parts.push(data[start..].to_vec());
751    }
752
753    parts
754}
755impl Default for Body {
756    fn default() -> Self {
757        Self {
758            content_type: ContentType::Other("text/plain".to_string()),
759            boundary: String::new(),
760            content_length: 0,
761            content: object! {},
762        }
763    }
764}
765/// 消息内容
766#[derive(Clone, Debug)]
767pub enum Content {
768    FormUrlencoded(JsonValue),
769    FormData(JsonValue),
770    Json(JsonValue),
771    Text(JsonValue),
772    Xml(JsonValue),
773    None,
774}
775impl Content {}
776#[derive(Clone, Debug)]
777pub enum FormData {
778    File(String, PathBuf),
779    Field(JsonValue),
780}
781
782#[derive(Clone, Debug)]
783pub enum Upgrade {
784    Websocket,
785    Http,
786    None,
787}
788impl Upgrade {
789    #[must_use]
790    pub fn from(name: &str) -> Self {
791        match name.to_lowercase().as_str() {
792            "websocket" => Self::Websocket,
793            "http" => Self::Http,
794            _ => Self::None,
795        }
796    }
797    pub fn str(&mut self) -> String {
798        match self {
799            Self::Websocket => "websocket",
800            Self::Http => "http",
801            Self::None => "",
802        }.to_string()
803    }
804}
805
806#[derive(Clone, Debug)]
807pub enum Connection {
808    KeepAlive,
809    Close,
810    Upgrade,
811    None,
812}
813impl Connection {
814    #[must_use]
815    pub fn from(value: &str) -> Self {
816        match value.to_lowercase().as_str() {
817            "upgrade" => Self::Upgrade,
818            "keep-alive" => Self::KeepAlive,
819            "close" => Self::Close,
820            _ => Self::None,
821        }
822    }
823}