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#[derive(Clone, Debug)]
17pub struct Response {
18 pub request: Request,
19 pub status: Status,
20 pub headers: JsonValue,
21 pub cookies: JsonValue,
22 pub body: Vec<u8>,
24 pub stream_id: u32,
26 pub key: String,
28 pub version: String,
30 pub factory: fn(out: Websocket) -> Box<dyn Handler>,
31 pub allow_origins: Vec<&'static str>,
33 pub allow_methods: Vec<&'static str>,
35 pub allow_headers: Vec<&'static str>,
37 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; 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 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 pub fn location(&mut self, uri: &str) -> &mut Self {
236 self.header("Location", uri);
237 self
238 }
239 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); future.format("%a, %d %b %Y %H:%M:%S GMT").to_string()
257 }
258 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 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 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 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 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 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 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 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 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(); }
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 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 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 }); 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 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); 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
618enum 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