br_web_server/
response.rs

1use crate::Status;
2use crate::request::{Request};
3use chrono::{DateTime, Duration as dur, Utc};
4use json::{object, JsonValue};
5use log::{error, 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, Protocol, Upgrade};
11use crate::Protocol::HTTP2;
12use crate::websocket::Websocket;
13const FLAG_END_STREAM: u8 = 0x01;
14const FLAG_END_HEADERS: u8 = 0x04;
15/// 响应
16#[derive(Clone, Debug)]
17pub struct Response {
18    pub request: Request,
19    pub status: Status,
20    pub headers: JsonValue,
21    pub cookies: JsonValue,
22    /// 消息体
23    pub body: Vec<u8>,
24    /// HTTP2 使用
25    pub stream_id: u32,
26    /// ws 通信密钥
27    pub key: String,
28    /// ws 版本
29    pub version: String,
30    pub factory: fn(out: Websocket) -> Box<dyn Handler>,
31    /// 允许来源
32    pub allow_origins: Vec<&'static str>,
33    /// 允许方法
34    pub allow_methods: Vec<&'static str>,
35    /// 允许请求头
36    pub allow_headers: Vec<&'static str>,
37    /// 消息体类型
38    pub content_type: ContentType,
39}
40impl Response {
41    pub fn new(request: &Request, factory: fn(out: Websocket) -> Box<dyn Handler>) -> Self {
42        Self {
43            request: request.clone(),
44            status: Status::default(),
45            headers: object! {},
46            cookies: object! {},
47            body: vec![],
48            stream_id: 0,
49            key: String::new(),
50            version: String::new(),
51            factory,
52            allow_origins: vec![],
53            allow_methods: vec![],
54            allow_headers: vec![],
55            content_type: ContentType::Other(String::new()),
56        }
57    }
58    pub fn handle(mut self) -> io::Result<()> {
59        match self.request.upgrade {
60            Upgrade::Websocket => {
61                self.handle_protocol_ws()?;
62                return Ok(());
63            }
64            Upgrade::Http | Upgrade::Other(_) => {}
65            Upgrade::H2c => {
66                let _ = self.handle_protocol_h2c();
67            }
68            }
69
70        match self.request.protocol {
71            Protocol::HTTP1_0 => self.handle_protocol_http0()?,
72            Protocol::HTTP1_1 => self.handle_protocol_http1()?,
73            Protocol::HTTP2 => self.handle_protocol_http2()?,
74            Protocol::HTTP3 | Protocol::Other(_) => {}
75            }
76        Ok(())
77    }
78    fn handle_protocol_http0(&mut self) -> io::Result<()> {
79        let websocket = Websocket::http(self.request.clone(), self.clone());
80        let mut factory = (self.factory)(websocket);
81        match self.request.method {
82            Method::OPTIONS => {
83                factory.on_options(self);
84                match self.on_options() {
85                    Ok(()) => {
86                        match self.status(200).send() {
87                            Ok(()) => {}
88                            Err(e) => return Err(Error::other(format!("1004: {} {} {}", self.request.uri.path, e.code, e.body))),
89                        }
90                    }
91                    Err(e) => return {
92                        self.status(e.code).txt(e.body.as_str()).send().unwrap();
93                        Ok(())
94                    }
95                }
96            }
97            Method::GET => {
98                if let Ok(e) = self.read_resource() {
99                    if self.request.header.has_key("range") {
100                        return match self.status(206).range(&e).send() {
101                            Ok(()) => Ok(()),
102                            Err(e) => Err(Error::other(format!("1003: {} {} {}", self.request.uri.path, e.code, e.body))),
103                        };
104                    }
105                    return match self.status(200).file(&e).send() {
106                        Ok(_) => Ok(()),
107                        Err(e) => Err(Error::other(format!("1003: {} {} {}", self.request.uri.path, e.code, e.body))),
108                    };
109                }
110                factory.on_request(self.request.clone(), self);
111                factory.on_response(self);
112                match self.send() {
113                    Ok(()) => {}
114                    Err(e) => return Err(Error::other(format!("1002: {} {} {}", self.request.uri.path, e.code, e.body))),
115                }
116            }
117            _ => {
118                factory.on_request(self.request.clone(), self);
119                factory.on_response(self);
120                match self.send() {
121                    Ok(_) => {}
122                    Err(e) => return Err(Error::other(format!("1001: {} {}", e.code, e.body))),
123                }
124            }
125        }
126        Ok(())
127    }
128    fn handle_protocol_http1(&mut self) -> io::Result<()> {
129        self.handle_protocol_http0()
130    }
131    fn handle_protocol_http2(&mut self) -> io::Result<()> {
132        let websocket = Websocket::http(self.request.clone(), self.clone());
133        let mut factory = (self.factory)(websocket);
134
135        match self.request.method {
136            Method::OPTIONS => {
137                factory.on_options(self);
138                match self.send() {
139                    Ok(_) => {}
140                    Err(e) => return Err(Error::other(format!("2001: {} {}", e.code, e.body))),
141                };
142            }
143            Method::GET => {
144                if let Ok(e) = self.read_resource() {
145                    return match self.status(200).file(&e).send() {
146                        Ok(_) => Ok(()),
147                        Err(e) => Err(Error::other(e.body)),
148                    };
149                }
150                factory.on_request(self.request.clone(), self);
151                factory.on_response(self);
152                match self.send() {
153                    Ok(()) => {}
154                    Err(e) => return Err(Error::other(format!("2002: {} {}", e.code, e.body))),
155                }
156            }
157            _ => {
158                factory.on_request(self.request.clone(), self);
159                factory.on_response(self);
160                match self.send() {
161                    Ok(_) => {}
162                    Err(e) => return Err(Error::other(format!("2003: {} {}", e.code, e.body))),
163                }
164            }
165        }
166        Ok(())
167    }
168    fn handle_protocol_ws(&mut self) -> io::Result<()> {
169        let mut websocket = Websocket::new(self.request.clone(), self.clone());
170        let _ = websocket.handle();
171        Ok(())
172    }
173    fn handle_protocol_h2c(&mut self) -> Result<(), HttpError> {
174        self.header("Upgrade", "h2c");
175        self.header("Connection", "Upgrade");
176        match self.status(101).send() {
177            Ok(()) => self.headers.clear(),
178            Err(e) => return Err(e)
179        };
180        self.request.protocol=HTTP2;
181        self.request.scheme.lock().unwrap().http2_send_server_settings()?;
182        let mut data = vec![];
183        self.request.scheme.lock().unwrap().read(&mut data)?;
184
185        let t = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
186        if let Some(pos) = data.windows(t.len()).position(|window| window == t) {
187            let _ = data.drain(..pos).collect::<Vec<u8>>();
188            data.drain(..t.len());
189        } else {
190            return Err(HttpError::new(400, "请求行错误"));
191        }
192        let (_payload, _frame_type, flags, _stream_id) =  self.request.scheme.lock().unwrap().http2_packet(&mut data)?;
193        if flags & 0x01 == 0 {
194            self.request.scheme.lock().unwrap().http2_settings_ack()?;
195        }
196        let (_payload, _frame_type, _flags, _stream_id) =  self.request.scheme.lock().unwrap().http2_packet(&mut data)?;
197        let (payload, _frame_type, _flags, _stream_id) =  self.request.scheme.lock().unwrap().http2_packet(&mut data)?;
198        if payload.len() == 4 {
199            let raw = u32::from_be_bytes(payload.clone().try_into().unwrap());
200            let increment = raw & 0x7FFF_FFFF; // 屏蔽最高位保留位
201            if self.request.config.debug {
202                info!("WindowUpdate: increment = {} {:?}", increment,payload);
203            }
204        } else {
205            return Err(HttpError::new(400, format!("Invalid WindowUpdate frame length: {}", payload.len()).as_str()));
206        }
207        Ok(())
208    }
209    /// 读取资源文件
210    fn read_resource(&mut self) -> io::Result<PathBuf> {
211        if self.request.uri.path != "/" {
212            let file = self.request.config.root_path.join(self.request.config.public.clone()).join(self.request.uri.path.trim_start_matches('/'));
213            if file.is_file() {
214                return Ok(file);
215            }
216        }
217        if self.request.uri.path == "/" {
218            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join("index.html");
219            if file.is_file() {
220                return Ok(file);
221            }
222        } else {
223            let file = self.request.config.root_path.join("webpage").join(self.request.config.webpage.clone()).join(self.request.uri.path.trim_start_matches('/'));
224            if file.is_file() {
225                return Ok(file);
226            }
227        }
228        Err(Error::other("Not a file"))
229    }
230    pub fn status(&mut self, code: u16) -> &mut Self {
231        self.status.set_code(code);
232        self
233    }
234    /// 跳转
235    pub fn location(&mut self, uri: &str) -> &mut Self {
236        self.header("Location", uri);
237        self
238    }
239    /// 设置 HOST
240    pub fn set_host(&mut self, host: &str) -> &mut Self {
241        self.header("Host", host);
242        self
243    }
244
245    pub fn header(&mut self, key: &str, value: &str) -> &mut Self {
246        self.headers[key] = value.into();
247        self
248    }
249    pub fn cookie(&mut self, key: &str, value: &str) -> &mut Self {
250        self.cookies[key] = value.into();
251        self
252    }
253    fn get_date(&self, s: i64) -> String {
254        let utc: DateTime<Utc> = Utc::now();
255        let future = utc + dur::seconds(s); // 加 3600 秒 = 1 小时
256        future.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
257    }
258    /// HTML 返回
259    pub fn html(&mut self, value: &str) -> &mut Self {
260        if self.request.config.charset.is_empty() {
261            self.header("Content-Type", format!("{};", Extension::form("html").as_str()).as_str());
262        } else {
263            self.header("Content-Type", format!("{}; charset={}", Extension::form("html").as_str(), self.request.config.charset).as_str());
264        }
265        self.content_type = ContentType::Html;
266        self.body = value.as_bytes().to_vec();
267        self
268    }
269    /// TXT 返回
270    pub fn txt(&mut self, value: &str) -> &mut Self {
271        if self.request.config.charset.is_empty() {
272            self.header("Content-Type", Extension::form("txt").as_str().to_string().as_str());
273        } else {
274            self.header("Content-Type", format!("{}; charset={}", Extension::form("txt").as_str(), self.request.config.charset).as_str());
275        }
276        self.content_type = ContentType::Text;
277        self.body = value.as_bytes().to_vec();
278        self
279    }
280    /// JSON 返回
281    pub fn json(&mut self, value: JsonValue) -> &mut Self {
282        if self.request.config.charset.is_empty() {
283            self.header("Content-Type", Extension::form("json").as_str().to_string().as_str());
284        } else {
285            self.header("Content-Type", format!("{}; charset={}", Extension::form("json").as_str(), self.request.config.charset).as_str());
286        }
287        self.content_type = ContentType::Json;
288        self.body = value.to_string().into_bytes();
289        self
290    }
291    /// 下载 返回
292    ///
293    /// # Panics
294    ///
295    /// This function will panic if:
296    /// - `filename.extension()` returns `None`
297    /// - The extension cannot be converted to a valid UTF-8 string
298    /// - The filename cannot be converted to a valid UTF-8 string
299    pub fn download(&mut self, filename: &Path) -> &mut Self {
300        let Ok(file) = fs::read(filename) else {
301            self.status(404);
302            return self;
303        };
304        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();
305
306        if self.request.config.charset.is_empty() {
307            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
308        } else {
309            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
310        }
311
312        let encoded_file_name = br_crypto::encoding::urlencoding_encode(filename.file_name().unwrap().to_str().unwrap());
313        self.header("Content-Disposition", format!(r"attachment; filename={encoded_file_name}").as_str());
314        self.header("Cache-Control", "no-cache");
315        self.header("ETag", br_crypto::md5::encrypt_hex(&file).as_str());
316        self.body = file;
317        self
318    }
319    /// 分片
320    pub fn range(&mut self, filename: &Path) -> &mut Self {
321        let Ok(file) = fs::read(filename) else {
322            self.status(404);
323            return self;
324        };
325        let range = self.request.header["range"].to_string();
326        let range = range.trim_start_matches("bytes=");
327        let range = range.split("-").collect::<Vec<&str>>();
328        let range_start = range[0].parse::<usize>().unwrap();
329        let range_end = range[1].parse::<usize>().unwrap();
330
331        if file.len() < range_end {
332            self.status(416);
333            self.header("Content-Range", format!("bytes */{}", file.len()).as_str());
334            return self;
335        }
336
337        let extension = filename.extension().unwrap().to_str().unwrap().to_lowercase();
338
339        if self.request.config.charset.is_empty() {
340            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
341        } else {
342            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
343        }
344
345        self.header("Accept-Ranges", "bytes");
346        self.header("content-length", (range_end - range_start + 1).to_string().as_str());
347        self.header("Content-Range", format!("bytes {}-{}/{}", range_start, range_end, file.len()).as_str());
348        self.body = file[range_start..=range_end].to_vec();
349        self
350    }
351    /// Serves a file for inline display in the browser.
352    ///
353    /// # 文件返回
354    ///
355    /// This function will panic if the file extension cannot be converted to a string,
356    /// or if the filename cannot be converted to a valid UTF-8 string.
357    pub fn file(&mut self, filename: &Path) -> &mut Self {
358        let Ok(file) = fs::read(filename) else {
359            self.status(404);
360            return self;
361        };
362
363        self.header("Access-Control-Expose-Headers", "Content-Disposition");
364        let extension = match filename.extension() {
365            None => String::new(),
366            Some(e) => e.to_str().unwrap().to_lowercase(),
367        };
368        if self.request.config.charset.is_empty() {
369            self.header("Content-Type", Extension::form(extension.as_str()).as_str().to_string().as_str());
370        } else {
371            self.header("Content-Type", format!("{}; charset={}", Extension::form(extension.as_str()).as_str(), self.request.config.charset).as_str());
372        }
373
374        self.header("Content-Disposition", format!(r#"inline; filename="{}""#, filename.file_name().unwrap().to_str().unwrap()).as_str());
375
376        self.header("Accept-Ranges", "bytes");
377
378        self.header("Cache-Control", format!("public, max-age={}", 81400).as_str());
379        self.header("Expires", &self.clone().get_date(81400));
380        self.body = file;
381        self
382    }
383    /// Sends the response over the given scheme.
384    ///
385    /// # Errors
386    ///
387    /// Returns an error if writing the response over the scheme fails.
388    pub fn send(&mut self) -> Result<(), HttpError> {
389        match &self.request.protocol {
390            Protocol::HTTP1_0 | Protocol::HTTP1_1 => Ok(self.send_http1()?),
391            Protocol::HTTP2 => Ok(self.send_http2()?),
392            Protocol::HTTP3 => {
393                error!("Other1:{:?} {:?}", thread::current().id(),self.request);
394                Err(HttpError::new(500, "暂未实现HTTP3"))
395            }
396            Protocol::Other(e) => {
397                error!("Other:{:?} {:?}", thread::current().id(),self.request);
398                Err(HttpError::new(500, format!("暂未实现Other: {} {} {:?}", e, self.request.uri.path, thread::current().id()).as_str()))
399            }
400        }
401    }
402    fn send_http1(&mut self) -> Result<(), HttpError> {
403        let mut header = vec![];
404        header.push(format!("{} {} {}", self.request.protocol.str(), self.status.code, self.status.reason));
405        self.header("Date", &self.get_date(0));
406
407        match self.request.method {
408            Method::HEAD => {
409                self.header("Content-Length", self.body.len().to_string().as_str());
410                self.body = vec![];
411            }
412            Method::OPTIONS => {
413                self.body = vec![];
414            }
415            _ => {
416                match self.request.accept_encoding {
417                    Encoding::Gzip => {
418                        self.header("Content-Encoding", self.request.accept_encoding.clone().str());
419                        if let Ok(e) = self.request.accept_encoding.compress(&self.body.clone()) { self.body = e };
420                        self.header("Content-Length", self.body.len().to_string().as_str());
421                    }
422                    _ => { self.header("Content-Length", self.body.len().to_string().as_str()); }
423                }
424            }
425        };
426
427        for (key, value) in self.headers.entries() {
428            header.push(format!("{key}: {value}"));
429        }
430
431        for (key, value) in self.cookies.entries() {
432            header.push(format!("Set-Cookie: {key}={value}; Path=/; HttpOnly; SameSite=Lax"));
433        }
434
435        if self.request.config.debug {
436            info!("\r\n=================响应信息 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),header.join("\r\n"));
437            match self.request.accept_encoding {
438                Encoding::Gzip => {}
439                _ => {
440                    match self.content_type {
441                        ContentType::Text | ContentType::Html | ContentType::Json | ContentType::FormUrlencoded => {
442                            info!("\r\n=================响应体 {:?}=================\r\n{}\r\n===========================================",thread::current().id(),String::from_utf8_lossy(self.body.as_slice()));
443                        }
444                        _ => {}
445                    };
446                }
447            }
448        }
449        let mut headers = format!("{}\r\n\r\n", header.join("\r\n")).into_bytes();
450        headers.extend(self.body.clone());
451        self.request.scheme.lock().unwrap().write_all(headers.as_slice())?;
452        Ok(())
453    }
454    fn send_http2(&mut self) -> Result<(), HttpError> {
455
456        let max_frame_size: usize = 16_384;
457        self.stream_id += 1;
458        // 先构建所有帧,避免持锁期间借用 self
459        let header_frames = self.http2_header(self.stream_id, max_frame_size);
460        let data_frames = self.http2_body(self.stream_id, true, max_frame_size);
461
462        // 仅锁一次写端,顺序写出所有帧
463        let mut writer = self.request.scheme.lock().unwrap();
464        for f in header_frames.clone() { writer.write_all(&f)?; }
465        for f in data_frames.clone() { writer.write_all(&f)?; }
466        Ok(())
467    }
468
469    fn http2_header(&mut self, stream_id: u32, max_frame_size: usize) -> Vec<Vec<u8>> {
470        let mut headers: Vec<(Vec<u8>, Vec<u8>)> = vec![
471            (b":status".to_vec(), self.status.code.to_string().into_bytes()),
472            (b"date".to_vec(), self.get_date(0).into_bytes()),
473        ];
474
475        match self.request.method {
476            Method::HEAD => {
477                self.header("content-length", self.body.len().to_string().as_str());
478                self.body.clear(); // HEAD 响应不携带实体
479            }
480            Method::OPTIONS => {
481                self.body.clear();
482                self.header("content-length", "0");
483            }
484            _ => {
485                self.header("content-length", self.body.len().to_string().as_str());
486            }
487        }
488
489        headers.extend(
490            self.headers.entries().map(|(k, v)| (k.to_string().to_lowercase().into_bytes(), v.to_string().into_bytes()))
491        );
492        headers.extend(
493            self.cookies.entries().map(|(k, v)| (b"set-cookie".to_vec(), format!("{k}={v}; Path=/; HttpOnly; SameSite=Lax").into_bytes()))
494        );
495
496        if self.request.config.debug {
497            let dbg = headers.iter().map(|(n, v)| {
498                format!("{}: {}", String::from_utf8_lossy(n), String::from_utf8_lossy(v))
499            }).collect::<Vec<_>>().join("\r\n");
500            info!("\n=================响应信息 {:?}=================\n{}\n===========================================",
501              std::thread::current().id(), dbg);
502        }
503
504        let mut encoder = Encoder::new();
505        // 2) HPACK 编码
506        let block = encoder.encode(headers.iter().map(|h| (&h.0[..], &h.1[..])));
507
508        let end_stream = self.body.is_empty();
509        let mut frames = Vec::new();
510        let mut remaining = block.as_slice();
511        let mut first = true;
512
513        while !remaining.is_empty() {
514            let take = remaining.len().min(max_frame_size);
515            let (chunk, rest) = remaining.split_at(take);
516            remaining = rest;
517
518            let is_last = remaining.is_empty();
519            let mut flags = 0u8;
520            if is_last { flags |= FLAG_END_HEADERS; }
521            if is_last && end_stream { flags |= FLAG_END_STREAM; }
522
523            // 9字节帧头
524            let mut f = Vec::with_capacity(9 + chunk.len());
525            let len = chunk.len();
526            f.push(((len >> 16) & 0xFF) as u8);
527            f.push(((len >> 8) & 0xFF) as u8);
528            f.push((len & 0xFF) as u8);
529            f.push(if first { 0x01 } else { 0x09 }); // HEADERS / CONTINUATION
530            f.push(flags);
531            f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
532            f.extend_from_slice(chunk);
533
534            frames.push(f);
535            first = false;
536        }
537
538        // 如果 block 为空(极少见),也要至少发一个空 HEADERS(END_HEADERS [+END_STREAM])
539        if frames.is_empty() {
540            let mut f = vec![0, 0, 0, 0x01, FLAG_END_HEADERS | if end_stream { FLAG_END_STREAM } else { 0 }, 0, 0, 0, 0];
541            f[5..9].copy_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
542            frames.push(f);
543        }
544
545        frames
546    }
547    fn http2_body(&mut self, stream_id: u32, end_stream: bool, max_frame_size: usize) -> Vec<Vec<u8>> {
548        if self.body.is_empty() {
549            return Vec::new();
550        }
551        let mut frames = Vec::new();
552        let mut off = 0usize;
553        let total = self.body.len();
554
555        while off < total {
556            let take = (total - off).min(max_frame_size);
557            let chunk = &self.body[off..off + take];
558            off += take;
559
560            let last = off == total;
561            frames.push(self.build_data_frame(stream_id, chunk, last && end_stream));
562        }
563        frames
564    }
565    fn build_data_frame(&self, stream_id: u32, payload: &[u8], end_stream: bool) -> Vec<u8> {
566        let len = payload.len();
567        let mut f = Vec::with_capacity(9 + len);
568        f.push(((len >> 16) & 0xFF) as u8);
569        f.push(((len >> 8) & 0xFF) as u8);
570        f.push((len & 0xFF) as u8);
571        f.push(0x00); // DATA
572        f.push(if end_stream { FLAG_END_STREAM } else { 0 });
573        f.extend_from_slice(&(stream_id & 0x7FFF_FFFF).to_be_bytes());
574        if !payload.is_empty() { f.extend_from_slice(payload); }
575        f
576    }
577    fn on_options(&mut self) -> Result<(), HttpError> {
578        if self.allow_origins.is_empty() {
579            self.header("Access-Control-Allow-Origin", "*");
580        } else if self.request.header.has_key("origin") {
581            if self.allow_origins.contains(&self.request.origin.as_str()) {
582                self.header("Access-Control-Allow-Origin", self.request.origin.to_string().as_str());
583            } else {
584                return Err(HttpError::new(403, "Origin not allowed"));
585            }
586        } else {
587            return Err(HttpError::new(403, "Origin not allowed"));
588        }
589
590        if self.allow_headers.is_empty() {
591            if !self.request.header.has_key("access-control-request-headers") {
592                return Err(HttpError::new(403, "headers not allowed"));
593            }
594            self.header("Access-Control-Allow-Headers", self.request.header["access-control-request-headers"].to_string().as_str());
595        } else if !self.request.header.has_key("access-control-request-headers") {
596            let headers = self.allow_headers.join(",");
597            self.header("Access-Control-Allow-Headers", headers.to_string().as_str());
598        } else {
599            let headers = self.allow_headers.join(",");
600            self.header("Access-Control-Allow-Headers", format!("{},{}", self.request.header["access-control-request-headers"], headers).as_str());
601        }
602
603        if self.allow_methods.is_empty() {
604            if !self.request.header.has_key("access-control-request-method") {
605                return Err(HttpError::new(403, "methods not allowed"));
606            }
607            self.header("Access-Control-Allow-Methods", self.request.header["access-control-request-method"].to_string().as_str());
608        } else {
609            let methods = self.allow_methods.join(",");
610            self.header("Access-Control-Allow-Methods", methods.to_string().as_str());
611        }
612        self.header("Vary", "Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
613        Ok(())
614    }
615}
616
617
618/// 文件类型
619enum Extension {}
620impl Extension {
621    pub fn form(extension: &str) -> String {
622        match extension.to_lowercase().as_str() {
623            "html" => "text/html",
624            "css" => "text/css",
625            "js" => "application/javascript",
626            "json" => "application/json",
627            "png" => "image/png",
628
629            "mp4" => "video/mp4",
630            "jpg" | "jpeg" => "image/jpeg",
631            "gif" => "image/gif",
632            "txt" => "text/plain",
633            "pdf" => "application/pdf",
634            "svg" => "image/svg+xml",
635            "woff" => "application/font-woff",
636            "woff2" => "application/font-woff2",
637            "xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
638            _ => "application/octet-stream",
639        }.to_string()
640    }
641}
642
643