br_web_server/
response.rs

1use crate::stream::{Protocol};
2use crate::request::{Request};
3use chrono::{DateTime, Duration as dur, Utc};
4use json::{object, JsonValue};
5use log::{info};
6use std::path::{Path, PathBuf};
7use std::{fs, io, thread};
8use std::io::Error;
9use hpack::Encoder;
10use crate::{ContentType, Encoding, Handler, HttpError, Method, Upgrade};
11use crate::websocket::Websocket;
12const FLAG_END_STREAM: u8 = 0x01;
13const FLAG_END_HEADERS: u8 = 0x04;
14/// 响应
15#[derive(Clone, Debug)]
16pub struct Response {
17    pub request: Request,
18    pub status: Status,
19    pub headers: JsonValue,
20    pub cookies: JsonValue,
21    /// 消息体
22    pub body: Vec<u8>,
23    /// HTTP2 使用
24    pub stream_id: u32,
25    /// ws 通信密钥
26    pub key: String,
27    /// ws 版本
28    pub version: String,
29    pub factory: fn(out: Websocket) -> Box<dyn Handler>,
30    /// 允许来源
31    pub allow_origins: Vec<&'static str>,
32    /// 允许方法
33    pub allow_methods: Vec<&'static str>,
34    /// 允许请求头
35    pub allow_headers: Vec<&'static str>,
36    /// 消息体类型
37    pub content_type: ContentType,
38}
39impl Response {
40    pub fn new(request: Request, factory: fn(out: Websocket) -> Box<dyn Handler>) -> Self {
41        Self {
42            request: request.clone(),
43            status: Status::default(),
44            headers: object! {},
45            cookies: object! {},
46            body: vec![],
47            stream_id: 0,
48            key: String::new(),
49            version: String::new(),
50            factory,
51            allow_origins: vec![],
52            allow_methods: vec![],
53            allow_headers: vec![],
54            content_type: ContentType::Other(String::new()),
55        }
56    }
57    pub fn handle(mut self) -> io::Result<()> {
58        if let Upgrade::Websocket = self.request.upgrade { self.handle_protocol_ws()? }
59
60        match self.request.protocol {
61            Protocol::HTTP1_0 => self.handle_protocol_http0()?,
62            Protocol::HTTP1_1 => self.handle_protocol_http1()?,
63            Protocol::HTTP2 => self.handle_protocol_http2()?,
64            Protocol::HTTP3 => {}
65            Protocol::Other(_) => {}
66        }
67        Ok(())
68    }
69    fn handle_protocol_http0(&mut self) -> io::Result<()> {
70        let websocket = Websocket::http(self.request.clone(), self.clone());
71        let mut factory = (self.factory)(websocket);
72        match self.request.method {
73            Method::OPTIONS => {
74                factory.on_options(self);
75                match self.on_options() {
76                    Ok(_) => {
77                        match self.status(200).send() {
78                            Ok(_) => {}
79                            Err(e) => return Err(Error::other(e.body)),
80                        };
81                    }
82                    Err(e) => return {
83                        self.status(e.code).txt(e.body.as_str()).send().unwrap();
84                        Ok(())
85                    }
86                };
87            }
88            Method::GET => {
89                if let Ok(e) = self.read_resource() {
90                    return match self.status(200).file(&e).send() {
91                        Ok(_) => Ok(()),
92                        Err(e) => Err(Error::other(e.body)),
93                    };
94                }
95                factory.on_request(self.request.clone(), self);
96                factory.on_response(self.request.clone(), self);
97                match self.send() {
98                    Ok(_) => {}
99                    Err(e) => return Err(Error::other(e.body)),
100                }
101            }
102            _ => {
103                factory.on_request(self.request.clone(), self);
104                factory.on_response(self.request.clone(), self);
105                match self.send() {
106                    Ok(_) => {}
107                    Err(e) => return Err(Error::other(e.body)),
108                }
109            }
110        }
111        Ok(())
112    }
113    fn handle_protocol_http1(&mut self) -> io::Result<()> {
114        self.handle_protocol_http0()
115    }
116    fn handle_protocol_http2(&mut self) -> io::Result<()> {
117        let websocket = Websocket::http(self.request.clone(), self.clone());
118        let mut factory = (self.factory)(websocket);
119        match self.request.method {
120            Method::OPTIONS => {
121                factory.on_options(self);
122                match self.send() {
123                    Ok(_) => {}
124                    Err(e) => return Err(Error::other(e.body)),
125                };
126            }
127            Method::GET => {
128                if let Ok(e) = self.read_resource() {
129                    return match self.status(200).file(&e).send() {
130                        Ok(_) => Ok(()),
131                        Err(e) => Err(Error::other(e.body)),
132                    };
133                }
134                factory.on_request(self.request.clone(), self);
135                factory.on_response(self.request.clone(), self);
136                match self.send() {
137                    Ok(_) => {}
138                    Err(e) => return Err(Error::other(e.body)),
139                }
140            }
141            _ => {
142                factory.on_request(self.request.clone(), self);
143                factory.on_response(self.request.clone(), self);
144                match self.send() {
145                    Ok(_) => {}
146                    Err(e) => return Err(Error::other(e.body)),
147                }
148            }
149        }
150        Ok(())
151        //let mut data=vec![];
152        //loop {
153        //    sleep(std::time::Duration::from_secs(1));
154        //    let res = match self.request.scheme.lock().unwrap().http2_handle_body(&mut data, self.request.clone()) {
155        //        Ok(e) => e,
156        //        Err(e) => {
157        //            return Ok(())
158        //        }
159        //    };
160        //    match self.request.handle_body(res.clone()) {
161        //        Ok(_) => {}
162        //        Err(_) => {}
163        //    };
164        //}
165    }
166    fn handle_protocol_ws(&mut self) -> io::Result<()> {
167        let mut websocket = Websocket::new(self.request.clone(), self.clone());
168        let _ = websocket.handle();
169        Ok(())
170    }
171    /// 读取资源文件
172    fn read_resource(&mut self) -> io::Result<PathBuf> {
173        if self.request.uri.path != "/" {
174            let file = self.request.config.root_path.join(self.request.config.public.clone()).join(self.request.uri.path.trim_start_matches('/'));
175            if file.is_file() {
176                return Ok(file);
177            }
178        }
179        if self.request.uri.path == "/" {
180            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join("index.html");
181            if file.is_file() {
182                return Ok(file);
183            }
184        } else {
185            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join(self.request.uri.path.trim_start_matches('/'));
186            if file.is_file() {
187                return Ok(file);
188            }
189        }
190        Err(Error::other("Not a file"))
191    }
192    pub fn status(&mut self, code: u16) -> &mut Self {
193        self.status.set_code(code);
194        self
195    }
196    /// 跳转
197    pub fn location(&mut self, uri: &str) -> &mut Self {
198        self.header("Location", uri);
199        self
200    }
201    /// 设置 HOST
202    pub fn set_host(&mut self, host: &str) -> &mut Self {
203        self.header("Host", host);
204        self
205    }
206
207    pub fn header(&mut self, key: &str, value: &str) -> &mut Self {
208        self.headers[key] = value.into();
209        self
210    }
211    pub fn cookie(&mut self, key: &str, value: &str) -> &mut Self {
212        self.cookies[key] = value.into();
213        self
214    }
215    fn get_date(&self, s: i64) -> String {
216        let utc: DateTime<Utc> = Utc::now();
217        let future = utc + dur::seconds(s); // 加 3600 秒 = 1 小时
218        future.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
219    }
220    /// HTML 返回
221    pub fn html(&mut self, value: &str) -> &mut Self {
222        if self.request.config.charset.is_empty() {
223            self.header("Content-Type", format!("{};", Extension::form("html").as_str()).as_str());
224        } else {
225            self.header("Content-Type", format!("{}; charset={}", Extension::form("html").as_str(), self.request.config.charset).as_str());
226        }
227        self.content_type = ContentType::Html;
228        self.body = value.as_bytes().to_vec();
229        self
230    }
231    /// TXT 返回
232    pub fn txt(&mut self, value: &str) -> &mut Self {
233        if self.request.config.charset.is_empty() {
234            self.header("Content-Type", Extension::form("txt").as_str().to_string().as_str());
235        } else {
236            self.header("Content-Type", format!("{}; charset={}", Extension::form("txt").as_str(), self.request.config.charset).as_str());
237        }
238        self.content_type = ContentType::Text;
239        self.body = value.as_bytes().to_vec();
240        self
241    }
242    /// JSON 返回
243    pub fn json(&mut self, value: JsonValue) -> &mut Self {
244        if self.request.config.charset.is_empty() {
245            self.header("Content-Type", Extension::form("json").as_str().to_string().as_str());
246        } else {
247            self.header("Content-Type", format!("{}; charset={}", Extension::form("json").as_str(), self.request.config.charset).as_str());
248        }
249        self.content_type = ContentType::Json;
250        self.body = value.to_string().into_bytes();
251        self
252    }
253    /// 下载 返回
254    ///
255    /// # Panics
256    ///
257    /// This function will panic if:
258    /// - `filename.extension()` returns `None`
259    /// - The extension cannot be converted to a valid UTF-8 string
260    /// - The filename cannot be converted to a valid UTF-8 string
261    pub fn download(&mut self, filename: &Path) -> &mut Self {
262        let Ok(file) = fs::read(filename) else {
263            self.status(404);
264            return self;
265        };
266        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();
267
268        if self.request.config.charset.is_empty() {
269            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
270        } else {
271            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
272        }
273
274        let encoded_file_name = br_crypto::encoding::urlencoding_encode(filename.file_name().unwrap().to_str().unwrap());
275        self.header("Content-Disposition", format!(r"attachment; filename={encoded_file_name}").as_str());
276        self.header("Cache-Control", "no-cache");
277        self.header("ETag", br_crypto::md5::encrypt_hex(&file).as_str());
278        self.body = file;
279        self
280    }
281    /// 分片
282    pub fn range(&mut self, range: &str, filename: &Path) -> &mut Self {
283        let Ok(file) = fs::read(filename) else {
284            self.status(404);
285            return self;
286        };
287        let range = range.trim_start_matches("bytes=");
288        let range = range.split("-").collect::<Vec<&str>>();
289        let range_start = range[0].parse::<usize>().unwrap();
290        let range_end = range[1].parse::<usize>().unwrap();
291
292        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();
293
294        if self.request.config.charset.is_empty() {
295            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
296        } else {
297            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
298        }
299
300        self.header("Accept-Ranges", "bytes");
301        self.header("content-length", (range_end - range_start + 1).to_string().as_str());
302        self.header("Content-Range", format!("bytes {}-{}/{}", range_start, range_end, file.len()).as_str());
303        self.body = file[range_start..=range_end].to_vec();
304        self
305    }
306    /// Serves a file for inline display in the browser.
307    ///
308    /// # Panics
309    ///
310    /// This function will panic if the file extension cannot be converted to a string,
311    /// or if the filename cannot be converted to a valid UTF-8 string.
312    pub fn file(&mut self, filename: &Path) -> &mut Self {
313        let Ok(file) = fs::read(filename) else {
314            self.status(404);
315            return self;
316        };
317
318        let extension = match filename.extension() {
319            None => String::new(),
320            Some(e) => e.to_str().unwrap().to_lowercase(),
321        };
322        if self.request.config.charset.is_empty() {
323            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
324        } else {
325            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
326        }
327        self.header("Content-Disposition", format!(r#"inline; filename="{}""#, filename.file_name().unwrap().to_str().unwrap()).as_str());
328        //let digest = md5::compute(file.clone());
329        //self.header("Cache-Control", "no-cache");
330        //self.header("ETag", format!("{digest:x}").as_str());
331        self.header("Cache-Control", format!("public, max-age={}", 1800).as_str());
332        self.header("Expires", &self.clone().get_date(1800));
333        //if self.config.max_age > 0 {
334        //    self.header("Cache-Control", format!("public, max-age={}", self.config.max_age).as_str());
335        //    self.header("Expires", &self.clone().get_date(self.config.max_age));
336        //} else {
337        //    self.header("Cache-Control", "no-cache");
338        //}
339
340        self.body = file;
341        self
342    }
343    /// Sends the response over the given scheme.
344    ///
345    /// # Errors
346    ///
347    /// Returns an error if writing the response over the scheme fails.
348    pub fn send(&mut self) -> Result<(), HttpError> {
349        match self.request.protocol {
350            Protocol::HTTP1_0 | Protocol::HTTP1_1 => Ok(self.send_http1()?),
351            Protocol::HTTP2 => Ok(self.send_http2()?),
352            Protocol::HTTP3 => Err(HttpError::new(500, "暂未实现")),
353            Protocol::Other(_) => Err(HttpError::new(500, "暂未实现")),
354        }
355    }
356    fn send_http1(&mut self) -> Result<(), HttpError> {
357        let mut header = vec![];
358        header.push(format!("{} {} {}", self.request.protocol.str(), self.status.code, self.status.reason));
359        self.header("Date", &self.get_date(0));
360        // 服务器标识设置
361        if !self.request.config.server.is_empty() {
362            self.header("Server", self.request.config.clone().server.as_str());
363        }
364        //match self.request.connection {
365        //    Connection::KeepAlive => self.header("Connection", Connection::KeepAlive.str()),
366        //    Connection::Close => self.header("Connection", Connection::Close.str()),
367        //    _ => self.header("Connection", Connection::Close.str())
368        //};
369        match self.request.method {
370            Method::HEAD => {
371                self.header("Content-Length", self.body.len().to_string().as_str());
372                self.body = vec![];
373            }
374            Method::OPTIONS => {
375                self.header("Content-Length", "0");
376                if self.request.config.debug {
377                    info!("{}",String::from_utf8_lossy(self.body.as_slice()));
378                }
379                self.body = vec![];
380            }
381            _ => {
382                match self.request.accept_encoding {
383                    Encoding::Gzip => {
384                        self.header("Content-Encoding", self.request.accept_encoding.clone().str());
385                        if let Ok(e) = self.request.accept_encoding.clone().compress(&self.body.clone()) { self.body = e };
386                        self.header("Content-Length", self.body.len().to_string().as_str());
387                    }
388                    _ => { self.header("Content-Length", self.body.len().to_string().as_str()); }
389                }
390            }
391        };
392
393        for (key, value) in self.headers.entries() {
394            header.push(format!("{key}: {value}"));
395        }
396
397        for (key, value) in self.cookies.entries() {
398            header.push(format!("Set-Cookie: {key}={value}; Path=/; HttpOnly; SameSite=Lax"));
399        }
400
401        if self.request.config.debug {
402            info!("\r\n=================响应信息 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),header.join("\r\n"));
403            match self.request.accept_encoding {
404                Encoding::Gzip => {}
405                _ => {
406                    match self.content_type {
407                        ContentType::Text | ContentType::Html | ContentType::Json | ContentType::FormUrlencoded => {
408                            info!("\r\n=================响应体 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),String::from_utf8_lossy(self.body.as_slice()));
409                        }
410                        _ => {}
411                    };
412                }
413            }
414        }
415        let mut headers = format!("{}\r\n\r\n", header.join("\r\n")).into_bytes();
416        headers.extend(self.body.clone());
417        self.request.scheme.lock().unwrap().write(headers.as_slice())?;
418        Ok(())
419    }
420    fn send_http2(&mut self) -> Result<(), HttpError> {
421        let max_frame_size: usize = 16_384;
422        let stream_id = 1u32;
423        // 先构建所有帧,避免持锁期间借用 self
424        let header_frames = self.http2_header(stream_id, max_frame_size);
425        // 如果 header 已经 END_STREAM(即没有 body),这里会返回空 Vec
426        let data_frames = self.http2_body(stream_id, true, max_frame_size);
427
428        // 仅锁一次写端,顺序写出所有帧
429        let mut writer = self.request.scheme.lock().unwrap();
430        for f in header_frames { writer.write(&f)?; }
431        for f in data_frames { writer.write(&f)?; }
432
433        //let header_data = self.http2_header(stream_id,max_frame_size);
434        //for header in header_data {
435        //    self.request.scheme.lock().unwrap().write(header.as_slice())?;
436        //    let data_frame = self.http2_body(stream_id, true);
437        //    self.request.scheme.lock().unwrap().write(data_frame.as_slice())?;
438        //}
439        Ok(())
440    }
441
442    fn http2_header(&mut self, stream_id: u32, max_frame_size: usize) -> Vec<Vec<u8>> {
443        let mut encoder = Encoder::new();
444
445        let mut headers: Vec<(Vec<u8>, Vec<u8>)> = vec![
446            (b":status".to_vec(), self.status.code.to_string().into_bytes()),
447            (b"date".to_vec(), self.get_date(0).into_bytes()),
448        ];
449
450        if !self.request.config.server.is_empty() {
451            self.header("server", self.request.config.server.to_string().as_str());
452        }
453
454        match self.request.method {
455            Method::HEAD => {
456                self.header("content-length", self.body.len().to_string().as_str());
457                self.body.clear(); // HEAD 响应不携带实体
458            }
459            Method::OPTIONS => {
460                self.header("content-length", self.body.len().to_string().as_str());
461                self.body.clear();
462            }
463            _ => {
464                self.header("content-length", self.body.len().to_string().as_str());
465            }
466        }
467
468        headers.extend(
469            self.headers.entries().map(|(k, v)| (k.to_string().to_lowercase().into_bytes(), v.to_string().into_bytes()))
470        );
471        headers.extend(
472            self.cookies.entries().map(|(k, v)| (b"set-cookie".to_vec(), format!("{k}={v}; Path=/; HttpOnly; SameSite=Lax").into_bytes()))
473        );
474
475        if self.request.config.debug {
476            let dbg = headers.iter().map(|(n, v)| {
477                format!("{}: {}", String::from_utf8_lossy(n), String::from_utf8_lossy(v))
478            }).collect::<Vec<_>>().join("\r\n");
479            info!("\n=================响应信息 {:?}=================\n{}\n===========================================",
480              std::thread::current().id(), dbg);
481        }
482
483        // 2) HPACK 编码
484        let block = encoder.encode(headers.iter().map(|h| (&h.0[..], &h.1[..])));
485
486        // 3) 拆分为 HEADERS + CONTINUATION...;如果 body 为空,需要在最后一块加 END_STREAM
487        let end_stream = self.body.is_empty();
488        let mut frames = Vec::new();
489        let mut remaining = block.as_slice();
490        let mut first = true;
491
492        while !remaining.is_empty() {
493            let take = remaining.len().min(max_frame_size);
494            let (chunk, rest) = remaining.split_at(take);
495            remaining = rest;
496
497            let is_last = remaining.is_empty();
498            let mut flags = 0u8;
499            if is_last { flags |= FLAG_END_HEADERS; }
500            if is_last && end_stream { flags |= FLAG_END_STREAM; }
501
502            // 9字节帧头
503            let mut f = Vec::with_capacity(9 + chunk.len());
504            let len = chunk.len();
505            f.push(((len >> 16) & 0xFF) as u8);
506            f.push(((len >> 8) & 0xFF) as u8);
507            f.push((len & 0xFF) as u8);
508            f.push(if first { 0x01 } else { 0x09 }); // HEADERS / CONTINUATION
509            f.push(flags);
510            f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
511            f.extend_from_slice(chunk);
512
513            frames.push(f);
514            first = false;
515        }
516
517        // 如果 block 为空(极少见),也要至少发一个空 HEADERS(END_HEADERS [+END_STREAM])
518        if frames.is_empty() {
519            let mut f = vec![0, 0, 0, 0x01, FLAG_END_HEADERS | if end_stream { FLAG_END_STREAM } else { 0 }, 0, 0, 0, 0];
520            f[5..9].copy_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
521            frames.push(f);
522        }
523
524        frames
525    }
526    fn http2_body(&mut self, stream_id: u32, end_stream: bool, max_frame_size: usize) -> Vec<Vec<u8>> {
527        // 取走 body,避免重复发送
528        let body = std::mem::take(&mut self.body);
529
530        // body 为空:如果需要结束流,发一帧空 DATA+END_STREAM;否则不发
531        if body.is_empty() {
532            return if end_stream {
533                vec![self.build_data_frame(stream_id, &[], true)]
534            } else {
535                Vec::new()
536            };
537        }
538
539        let mut frames = Vec::new();
540        let mut off = 0usize;
541        let total = body.len();
542
543        while off < total {
544            let take = (total - off).min(max_frame_size);
545            let chunk = &body[off..off + take];
546            off += take;
547
548            let last = off == total;
549            frames.push(self.build_data_frame(stream_id, chunk, last && end_stream));
550        }
551        frames
552    }
553    fn build_data_frame(&self, stream_id: u32, payload: &[u8], end_stream: bool) -> Vec<u8> {
554        let len = payload.len();
555        let mut f = Vec::with_capacity(9 + len);
556        f.push(((len >> 16) & 0xFF) as u8);
557        f.push(((len >> 8) & 0xFF) as u8);
558        f.push((len & 0xFF) as u8);
559        f.push(0x00); // DATA
560        f.push(if end_stream { FLAG_END_STREAM } else { 0 });
561        f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
562        if !payload.is_empty() { f.extend_from_slice(payload); }
563        f
564    }
565    fn on_options(&mut self) -> Result<(), HttpError> {
566        if self.allow_origins.is_empty() {
567            self.header("Access-Control-Allow-Origin", "*");
568        } else if self.request.header.has_key("origin") {
569            if self.allow_origins.contains(&self.request.origin.as_str()) {
570                self.header("Access-Control-Allow-Origin", self.request.origin.to_string().as_str());
571            } else {
572                return Err(HttpError::new(403, "Origin not allowed"));
573            }
574        } else {
575            return Err(HttpError::new(403, "Origin not allowed"));
576        }
577
578        if self.allow_headers.is_empty() {
579            if !self.request.header.has_key("access-control-request-headers") {
580                return Err(HttpError::new(403, "headers not allowed"));
581            }
582            self.header("Access-Control-Allow-Headers", self.request.header["access-control-request-headers"].to_string().as_str());
583        } else if !self.request.header.has_key("access-control-request-headers") {
584            let headers = self.allow_headers.join(",");
585            self.header("Access-Control-Allow-Headers", headers.to_string().as_str());
586        } else {
587            let headers = self.allow_headers.join(",");
588            self.header("Access-Control-Allow-Headers", format!("{},{}", self.request.header["access-control-request-headers"], headers).as_str());
589        }
590
591        if self.allow_methods.is_empty() {
592            if !self.request.header.has_key("access-control-request-method") {
593                return Err(HttpError::new(403, "methods not allowed"));
594            }
595            self.header("Access-Control-Allow-Methods", self.request.header["access-control-request-method"].to_string().as_str());
596        } else {
597            let methods = self.allow_methods.join(",");
598            self.header("Access-Control-Allow-Methods", methods.to_string().as_str());
599        }
600        self.header("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
601        // 允许前端跨域请求时发送和接收 cookie / 凭据
602        //if !self.headers.has_key("Access-Control-Expose-Headers") {
603        //    self.header("Access-Control-Expose-Headers", "true");
604        //}
605        // 允许前端访问请求头
606        //if !self.headers.has_key("Access-Control-Expose-Headers") {
607        //    self.header("Access-Control-Expose-Headers", "Content-Disposition");
608        //}
609        Ok(())
610    }
611}
612
613#[derive(Clone, Debug)]
614pub struct Status {
615    pub code: u16,
616    reason: String,
617}
618impl Status {
619    pub fn set_code(&mut self, code: u16) {
620        self.code = code;
621        self.reason = match code {
622            100 => "Continue", // 服务器愿意接收请求实体(配合 Expect: 100-continue)。
623            101 => "Switching Protocols", // 协议切换(如升级到 WebSocket)。
624            102 => "Processing",
625            103 => "Early Hints", // 提前提示可预加载的资源。
626            200 => "OK", // 请求成功(GET/PUT/PATCH 通用)
627            201 => "Created", // 已创建新资源(典型于 POST)
628            202 => "Accepted", // 已接受处理但未完成(异步任务)。
629            204 => "No Content", // 成功但无响应体(DELETE 常用)。
630            206 => "Partial Content", // 部分内容(Range 下载)。
631            301 => "Moved Permanently", // 永久重定向
632            302 => "Found", // 临时重定向(历史上易与 303/307混用)。
633            303 => "See Other", // 告诉客户端去 GET 另一个 URI(表单提交后跳详情页)。
634            304 => "Not Modified", // 资源未变更(配合缓存 ETag/Last-Modified)。
635            307 => "Temporary Redirect", // 临时,不改变方法(POST 仍是 POST)
636            308 => "Permanent Redirect", // 永久,不改变方法。
637
638            400 => "Bad Request", // 请求报文有误/语法错误/JSON 无法解析/缺少必需字段或头。
639            401 => "Unauthorized", // 未认证或凭证无效(要带 WWW-Authenticate)。
640            403 => "Forbidden",
641            404 => "Not Found", //服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
642            405 => "Method Not Allowed", // 方法不被允许(应返回 Allow 头)。
643            411 => "Length Required", // 缺少 Content-Length。
644            413 => "Payload Too Large", // 请求体过大。
645            414 => "URI Too Long", // URI 太长。
646            429 => "Too Many Requests", // 限流
647            431 => "Request Header Fields Too Large", // 请求头过大。
648
649            500 => "Internal Server Error", //服务器内部错误,无法完成请求
650            501 => "Not Implemented", //服务器不支持请求的功能,无法完成请求
651            502 => "Bad Gateway", //作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
652            503 => "Service Unavailable", //服务不可用/维护中(可带 Retry-After)。
653            504 => "Gateway Time-out",    //网关超时(上游响应超时)。
654            505 => "HTTP Version Not Supported", //服务器不支持请求的HTTP协议的版本,无法完成处理
655            _ => "",
656        }.to_string();
657    }
658}
659impl Default for Status {
660    fn default() -> Self {
661        Self {
662            code: 200,
663            reason: "OK".to_string(),
664        }
665    }
666}
667
668/// 文件类型
669enum Extension {}
670impl Extension {
671    pub fn form(extension: &str) -> String {
672        match extension {
673            "html" => "text/html",
674            "css" => "text/css",
675            "js" => "application/javascript",
676            "json" => "application/json",
677            "png" => "image/png",
678
679            "jpg" | "jpeg" => "image/jpeg",
680            "gif" => "image/gif",
681            "txt" => "text/plain",
682            "pdf" => "application/pdf",
683            "svg" => "image/svg+xml",
684            "woff" => "application/font-woff",
685            "woff2" => "application/font-woff2",
686            "xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
687            _ => "application/octet-stream",
688        }.to_string()
689    }
690}
691
692