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#[derive(Clone, Debug)]
16pub struct Response {
17 pub request: Request,
18 pub status: Status,
19 pub headers: JsonValue,
20 pub cookies: JsonValue,
21 pub body: Vec<u8>,
23 pub stream_id: u32,
25 pub key: String,
27 pub version: String,
29 pub factory: fn(out: Websocket) -> Box<dyn Handler>,
30 pub allow_origins: Vec<&'static str>,
32 pub allow_methods: Vec<&'static str>,
34 pub allow_headers: Vec<&'static str>,
36 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 }
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 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 pub fn location(&mut self, uri: &str) -> &mut Self {
198 self.header("Location", uri);
199 self
200 }
201 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); future.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
219 }
220 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 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 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 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 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 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 self.header("Cache-Control", format!("public, max-age={}", 1800).as_str());
332 self.header("Expires", &self.clone().get_date(1800));
333 self.body = file;
341 self
342 }
343 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 if !self.request.config.server.is_empty() {
362 self.header("Server", self.request.config.clone().server.as_str());
363 }
364 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 let header_frames = self.http2_header(stream_id, max_frame_size);
425 let data_frames = self.http2_body(stream_id, true, max_frame_size);
427
428 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 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(); }
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 let block = encoder.encode(headers.iter().map(|h| (&h.0[..], &h.1[..])));
485
486 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 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 }); 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 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 let body = std::mem::take(&mut self.body);
529
530 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); 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 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", 101 => "Switching Protocols", 102 => "Processing",
625 103 => "Early Hints", 200 => "OK", 201 => "Created", 202 => "Accepted", 204 => "No Content", 206 => "Partial Content", 301 => "Moved Permanently", 302 => "Found", 303 => "See Other", 304 => "Not Modified", 307 => "Temporary Redirect", 308 => "Permanent Redirect", 400 => "Bad Request", 401 => "Unauthorized", 403 => "Forbidden",
641 404 => "Not Found", 405 => "Method Not Allowed", 411 => "Length Required", 413 => "Payload Too Large", 414 => "URI Too Long", 429 => "Too Many Requests", 431 => "Request Header Fields Too Large", 500 => "Internal Server Error", 501 => "Not Implemented", 502 => "Bad Gateway", 503 => "Service Unavailable", 504 => "Gateway Time-out", 505 => "HTTP Version Not Supported", _ => "",
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
668enum 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