rust_xfinal/http_parser.rs
1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::fs::OpenOptions;
4use std::io::ErrorKind;
5use std::net::{Shutdown, TcpStream};
6
7use std::rc::Rc;
8use std::sync::Arc;
9use std::{io, io::prelude::*};
10
11use hmac::Hmac;
12use multimap::MultiMap;
13use sha2::Sha256;
14
15use std::collections::BTreeMap;
16
17use uuid;
18
19use chrono;
20
21pub mod websocket;
22
23pub use websocket::{Websocket, WebsocketEvent, WsMessage};
24
25pub mod connection;
26pub use connection::{
27 BodyContent, BodyType, MultipleFormData, MultipleFormFile, Request, Response,
28 ResponseChunkMeta, ResponseRangeMeta,
29};
30
31pub trait Router {
32 fn call(&self, req: &Request, res: &mut Response);
33}
34
35pub trait WsRouter {
36 fn call(&self, event: WebsocketEvent);
37}
38
39pub trait MiddleWare {
40 fn call(&self, req: &Request, res: &mut Response) -> bool;
41}
42
43pub type MiddleWareVec = Vec<Arc<dyn MiddleWare + Send + Sync>>;
44
45pub type RouterValue = (Option<MiddleWareVec>, Arc<dyn Router + Send + Sync>);
46
47pub type RouterMap = Arc<HashMap<String, RouterValue>>;
48
49pub type WsRouterValue = (Option<MiddleWareVec>, Arc<dyn WsRouter + Send + Sync>);
50
51pub type WsRouterMap = Arc<HashMap<String, WsRouterValue>>;
52
53impl<T> MiddleWare for T
54where
55 T: Fn(&Request, &mut Response) -> bool,
56{
57 fn call(&self, req: &Request, res: &mut Response) -> bool {
58 (*self)(req, res)
59 }
60}
61
62impl<T> Router for T
63where
64 T: Fn(&Request, &mut Response),
65{
66 fn call(&self, req: &Request, res: &mut Response) {
67 (*self)(req, res)
68 }
69}
70
71impl<T> WsRouter for T
72where
73 T: Fn(WebsocketEvent),
74{
75 fn call(&self, event: WebsocketEvent) {
76 (*self)(event);
77 }
78}
79
80#[derive(Clone)]
81pub struct ConnectionData {
82 pub(super) router_map: RouterMap,
83 pub(super) server_config: ServerConfig,
84 pub(super) ws_router_map: WsRouterMap,
85}
86#[derive(Clone)]
87pub struct ServerConfig {
88 pub(super) upload_directory: String,
89 pub(super) read_timeout: u32,
90 pub(super) chunk_size: u32,
91 pub(super) write_timeout: u32,
92 pub(super) open_log: bool,
93 pub(super) max_body_size: usize,
94 pub(super) max_header_size: usize,
95 pub(super) read_buff_increase_size: usize,
96 pub(super) secret_key: Arc<Hmac<Sha256>>,
97 pub(super) ws_read_timeout: u32,
98 pub(super) ws_write_timeout: u32,
99 pub(super) ws_frame_size: usize,
100}
101
102enum HasBody {
103 Len(usize),
104 None,
105 Bad,
106}
107
108pub(crate) fn get_current_date() -> String {
109 let now = chrono::Local::now();
110 let now = now.format("%Y-%m-%d %H:%M:%S");
111 now.to_string()
112}
113
114fn has_body(head_map: &HashMap<&str, &str>) -> HasBody {
115 let i = head_map.keys().find(|&&k| -> bool {
116 if k.to_lowercase() == "content-length" {
117 return true;
118 }
119 false
120 });
121 if let Some(&k) = i {
122 let v = head_map.get(k).unwrap(); // guaranteed by above
123 match v.parse::<usize>() {
124 Ok(size) => return HasBody::Len(size),
125 Err(_) => return HasBody::Bad,
126 }
127 } else {
128 return HasBody::None;
129 }
130}
131
132fn construct_http_event(
133 stream: &mut TcpStream,
134 router: &RouterMap,
135 method: &str,
136 url: &str,
137 version: &str,
138 head_map: HashMap<&str, &str>,
139 body: BodyContent,
140 _need_alive: bool,
141 server_config: &ServerConfig,
142) -> bool {
143 let conn = Rc::new(RefCell::new(stream));
144 let request = Request {
145 header_pair: head_map.clone(),
146 url,
147 method,
148 version,
149 body,
150 conn_: Rc::clone(&conn),
151 secret_key: Arc::clone(&server_config.secret_key),
152 ctx: RefCell::new(BTreeMap::new()),
153 };
154 let mut response = Response {
155 header_pair: MultiMap::new(),
156 version,
157 method,
158 //url,
159 http_state: 200,
160 body: BodyType::None,
161 chunked: ResponseChunkMeta::new(server_config.chunk_size),
162 conn_: Rc::clone(&conn),
163 range: ResponseRangeMeta::None,
164 request_header: head_map,
165 charset: None,
166 };
167
168 do_router(&router, &request, &mut response);
169 // if need_alive{
170 // response.add_header(String::from("Connection"), String::from("keep-alive"));
171 // }
172 let mut stream = conn.borrow_mut();
173 if !response.chunked.enable {
174 match write_once(*stream, &mut response) {
175 Ok(_) => {
176 return true;
177 }
178 Err(e) => {
179 if server_config.open_log {
180 let now = get_current_date();
181 println!(
182 "[{}] >>> error in write_once in http_parser.rs; type: [{}], line: [{}], msg: [{}]",
183 now,
184 e.kind().to_string(),
185 line!(),
186 ToString::to_string(&e)
187 );
188 }
189 return false;
190 }
191 }
192 } else {
193 // chunked transfer
194 match write_chunk(*stream, &mut response) {
195 Ok(_) => {
196 return true;
197 }
198 Err(e) => {
199 if server_config.open_log {
200 let now = get_current_date();
201 println!(
202 "[{}] >>> error in write_chunk in http_parser.rs; type: [{}], line: [{}], msg: [{}]",
203 now,
204 e.kind().to_string(),
205 line!(),
206 ToString::to_string(&e)
207 );
208 }
209 return false;
210 }
211 }
212 }
213}
214
215fn is_keep_alive(head_map: &HashMap<&str, &str>) -> bool {
216 let i = head_map.keys().find(|&&k| {
217 if k.to_lowercase() == "connection" {
218 true
219 } else {
220 false
221 }
222 });
223 match i {
224 Some(&k) => {
225 let &v = head_map.get(k).unwrap(); // guaranteed by above
226 if v.to_lowercase() == "keep-alive" {
227 true
228 } else {
229 false
230 }
231 }
232 None => false,
233 }
234}
235
236pub fn handle_incoming((conn_data, mut stream): (Arc<ConnectionData>, TcpStream)) {
237 let _ = stream.set_read_timeout(Some(std::time::Duration::from_millis(
238 conn_data.server_config.read_timeout as u64,
239 )));
240 let _ = stream.set_write_timeout(Some(std::time::Duration::from_millis(
241 conn_data.server_config.write_timeout as u64,
242 )));
243
244 // let mut buff = [b'\0';1024];
245 // let _ = stream.read(& mut buff);
246 // let response = "hello";
247 // let s = format!("HTTP/1.1 200 OK\r\nContent-length:{}\r\n\r\n{}",response.len(),response);
248 // let _ = stream.write(s.as_bytes());
249
250 'Back: loop {
251 let read_result = read_http_head(&mut stream, &conn_data.server_config);
252 if let Ok((mut head_content, possible_body)) = read_result {
253 let head_result = parse_header(&mut head_content);
254 // let response = "hello";
255 // let s = format!(
256 // "HTTP/1.1 200 OK\r\nContent-length:{}\r\n\r\n{}",
257 // response.len(),
258 // response
259 // );
260 // let _ = stream.write(s.as_bytes());
261 // break;
262
263 //println!("{:#?}", head_result.as_ref().unwrap());
264 match head_result {
265 Ok((method, url, version, map)) => {
266 let need_upgrade = websocket::is_websocket_upgrade(method, &map);
267 if need_upgrade.0 == true {
268 let ws_result = websocket::construct_http_event_for_websocket(
269 &mut stream,
270 method,
271 url,
272 version,
273 &map,
274 Arc::clone(&conn_data),
275 );
276 //println!("{}",ws_result.0);
277 if ws_result.0 {
278 let ws_version = need_upgrade.1;
279 let sec_websocket_key = need_upgrade.2;
280 websocket::handle_websocket_connection(
281 stream,
282 map,
283 ws_version,
284 sec_websocket_key,
285 ws_result.1.unwrap(),
286 conn_data,
287 );
288 }
289 return;
290 }
291 let need_alive = is_keep_alive(&map);
292 match has_body(&map) {
293 HasBody::Len(size) => match possible_body {
294 Some(partial_body) => {
295 let mut body = partial_body;
296 let body = read_body(
297 &mut stream,
298 &map,
299 &mut body,
300 size,
301 &conn_data.server_config,
302 );
303 if let BodyContent::Bad = body {
304 break;
305 }
306 if let BodyContent::TooLarge = body {
307 if conn_data.server_config.open_log {
308 let now = get_current_date();
309 println!(
310 "[{}] >>> error in handle_incoming in http_parser.rs; type: [body too large], line: [{}], msg: [the non-multipart-form body is too large]",
311 now,
312 line!()
313 );
314 }
315 break;
316 }
317 //println!("{:?}", body);
318 let r = construct_http_event(
319 &mut stream,
320 &conn_data.router_map,
321 method,
322 url,
323 version,
324 map,
325 body,
326 need_alive,
327 &conn_data.server_config,
328 );
329 if need_alive && r {
330 continue 'Back;
331 } else {
332 break;
333 }
334 }
335 None => {
336 //println!("in this logic, {}", size);
337 let mut body: Vec<u8> = Vec::new();
338 let body = read_body(
339 &mut stream,
340 &map,
341 &mut body,
342 size,
343 &conn_data.server_config,
344 );
345 if let BodyContent::Bad = body {
346 break;
347 }
348 if let BodyContent::TooLarge = body {
349 if conn_data.server_config.open_log {
350 let now = get_current_date();
351 println!(
352 "[{}] >>> error in handle_incoming in http_parser.rs; type: [body too large], line: [{}], msg: [the non-multipart-form body is too large]",
353 now,
354 line!()
355 );
356 }
357 break;
358 }
359 let r = construct_http_event(
360 &mut stream,
361 &conn_data.router_map,
362 method,
363 url,
364 version,
365 map,
366 body,
367 need_alive,
368 &conn_data.server_config,
369 );
370 if need_alive && r {
371 continue 'Back;
372 } else {
373 break;
374 }
375 }
376 },
377 HasBody::None => {
378 let r = construct_http_event(
379 &mut stream,
380 &conn_data.router_map,
381 method,
382 url,
383 version,
384 map,
385 BodyContent::None,
386 need_alive,
387 &conn_data.server_config,
388 );
389 if need_alive && r {
390 continue 'Back;
391 } else {
392 break;
393 }
394 }
395 HasBody::Bad => {
396 if conn_data.server_config.open_log {
397 let now = get_current_date();
398 println!(
399 "[{}] >>> error in handle_incoming in http_parser.rs; type: [bad body], line: [{}], msg: [invalid http body content]",
400 now,
401 line!()
402 );
403 }
404 let _ = stream.shutdown(Shutdown::Both);
405 break;
406 }
407 }
408 }
409 Err(e) => {
410 if conn_data.server_config.open_log {
411 let now = get_current_date();
412 println!(
413 "[{}] >>> error in parse_header in http_parser.rs; type:[{}], line: [{}], msg: [{}]",
414 now,
415 e.kind().to_string(),
416 line!(),
417 ToString::to_string(&e)
418 );
419 }
420 let _ = stream.shutdown(Shutdown::Both);
421 break;
422 }
423 }
424 } else if let Err(e) = read_result {
425 if conn_data.server_config.open_log {
426 let now = get_current_date();
427 println!(
428 "[{}] >>> error in reading http header in http_parser.rs; type: [{}], {}",
429 now,
430 e.kind().to_string(),
431 e.to_string()
432 );
433 }
434 let _ = stream.shutdown(Shutdown::Both);
435 break;
436 }
437 }
438 //println!("totally exit");
439}
440
441fn write_once(stream: &mut TcpStream, response: &mut Response) -> io::Result<()> {
442 if response.method == "HEAD" {
443 let s = response.header_to_string();
444 stream.write(&s)?;
445 stream.flush()?;
446 Ok(())
447 } else {
448 let mut lazy_buffs = response.take_body_buff()?;
449 let s = response.header_to_string();
450 let total_len = lazy_buffs.len();
451 let chunked_size = response.chunked.chunk_size;
452 let mut start = 0;
453 stream.write(&s)?;
454 stream.flush()?;
455 loop {
456 if start >= total_len {
457 break;
458 }
459 let mut end = start + chunked_size;
460 if end > total_len {
461 end = total_len;
462 }
463 let slice = lazy_buffs.get_slice_from_range(start..end)?; //&mut lazy_buffs[start..end];
464 stream.write(slice)?;
465 stream.flush()?;
466 start = end;
467 }
468 Ok(())
469 }
470}
471
472fn write_chunk(stream: &mut TcpStream, response: &mut Response) -> io::Result<()> {
473 let mut lazy_buffs = response.take_body_buff()?; //修改内部状态更新header头
474 let header = response.header_to_string();
475 let _ = stream.write(&header)?;
476 stream.flush()?;
477 if response.method == "HEAD" {
478 return Ok(());
479 }
480 let mut start = 0;
481 let chunked_size = response.chunked.chunk_size;
482 loop {
483 if start >= lazy_buffs.len() {
484 break;
485 }
486 let mut end = start + chunked_size;
487 if end > lazy_buffs.len() {
488 end = lazy_buffs.len();
489 }
490 let slice = lazy_buffs.get_slice_from_range(start..end)?; //&mut lazy_buffs[start..end];
491 let size = end - start;
492 let size = format!("{:X}", size);
493 stream.write(size.as_bytes())?;
494 stream.write(b"\r\n")?;
495 stream.write(slice)?;
496 stream.write(b"\r\n")?;
497 stream.flush()?;
498 start = end;
499 }
500 stream.write(b"0\r\n\r\n")?;
501 stream.flush()?;
502 Ok(())
503}
504
505// fn find_complete_header(slice: &[u8]) -> (bool, i32) {
506// let iter = slice.windows(2).into_iter();
507// for (pos, e) in iter.enumerate() {
508// if e == b"\r\n" {
509// if pos + 3 < slice.len() {
510// let second = &slice[pos + 2..=pos + 3];
511// if second == b"\r\n" {
512// return (true, pos as i32);
513// }
514// } else {
515// return (false, -1);
516// }
517// }
518// }
519// (false, -1)
520// }
521
522fn find_double_crlf(slice: &[u8]) -> (bool, i64) {
523 let double_crlf = b"\r\n\r\n";
524 match slice
525 .windows(double_crlf.len())
526 .position(|v| v == double_crlf)
527 {
528 Some(pos) => {
529 return (true, pos as i64);
530 }
531 None => {
532 return (false, -1);
533 }
534 }
535}
536
537fn read_http_head(
538 stream: &mut TcpStream,
539 server_config: &ServerConfig,
540) -> Result<(String, Option<Vec<u8>>), io::Error> {
541 let mut read_buffs = Vec::new();
542 read_buffs.resize(server_config.read_buff_increase_size, b'\0');
543 let mut total_read_size = 0;
544 let mut start_read_pos = 0;
545
546 loop {
547 match stream.read(&mut read_buffs[start_read_pos..]) {
548 //&mut read_buffs[start_read_pos..]
549 Ok(read_size) => {
550 if read_size == 0 {
551 let info = format!("line: [{}], msg: [lost connection]", line!());
552 let e = io::Error::new(io::ErrorKind::InvalidInput, info);
553 return Err(e);
554 }
555 total_read_size += read_size;
556 let slice = &read_buffs[..total_read_size];
557 let r = find_double_crlf(slice);
558 if r.0 {
559 let pos = r.1 as usize;
560 match std::str::from_utf8(&read_buffs[..pos]) {
561 Ok(s) => {
562 let crlf_end = pos + 4;
563 if total_read_size > crlf_end {
564 let mut body_buffs = Vec::new();
565 body_buffs.extend_from_slice(&slice[crlf_end..]);
566 return Ok((s.to_string(), Some(body_buffs)));
567 }
568 return Ok((s.to_string(), None));
569 }
570 Err(e) => {
571 let msg =
572 format!("line: [{}], msg: [{}]", line!(), ToString::to_string(&e));
573 let err = io::Error::new(io::ErrorKind::InvalidData, msg);
574 return Err(err);
575 }
576 }
577 } else {
578 if total_read_size > server_config.max_header_size {
579 let msg = format!("line: [{}], msg: [header too large]", line!());
580 let e = io::Error::new(io::ErrorKind::InvalidData, msg);
581 return Err(e);
582 }
583 start_read_pos = total_read_size;
584 let len = read_buffs.len();
585 read_buffs.resize(len + server_config.read_buff_increase_size, b'\0');
586 continue;
587 }
588 }
589 Err(e) => {
590 let msg = format!("line: [{}], msg: [{}]", line!(), ToString::to_string(&e));
591 let err = io::Error::new(e.kind(), msg);
592 return Err(err);
593 }
594 }
595 }
596}
597
598fn parse_header(
599 head_content: &mut String,
600) -> io::Result<(&str, &str, &str, HashMap<&'_ str, &'_ str>)> {
601 let mut head_map = HashMap::new();
602 match head_content.find("\r\n") {
603 Some(pos) => {
604 let url = &head_content[..pos];
605 //println!("url:{}",url);
606 let url_result: Vec<&str> = url
607 .split(" ")
608 .map(|item| {
609 let i = item.trim();
610 i
611 })
612 .collect();
613 // head_map.insert("method", url_result[0]);
614 // head_map.insert("url", url_result[1]);
615 // head_map.insert("http_version", url_result[2]);
616
617 let substr = &head_content[pos + 2..];
618 let result = substr.split("\r\n");
619 for item in result {
620 match item.split_once(":") {
621 Some((key, value)) => {
622 head_map.insert(key.trim(), value.trim());
623 }
624 None => {
625 let msg = format!("line: {}, invalid k/v pair in head", line!());
626 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
627 }
628 }
629 //head_map.insert(String::from(pair[0]),pair[1]);
630 }
631 //println!("{:#?}", head_map);
632 // method, url, version,header_pairs
633 Ok((url_result[0], url_result[1], url_result[2], head_map))
634 }
635 None => {
636 let msg = format!(
637 "line: {}, invalid Header:No METHOD URL VERSION\\r\\n",
638 line!()
639 );
640 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
641 }
642 }
643}
644
645fn invoke_router(result: &RouterValue, req: &Request, res: &mut Response) {
646 let router = &result.1;
647 match &result.0 {
648 Some(middlewares) => {
649 // at least one middleware
650 let mut r = true;
651 for middleware in middlewares {
652 if !middleware.call(req, res) {
653 r = false;
654 break;
655 }
656 }
657 if r {
658 router.call(req, res);
659 }
660 }
661 None => {
662 // there is no middleware
663 router.call(req, res);
664 }
665 }
666}
667
668fn do_router(router: &RouterMap, req: &Request, res: &mut Response) {
669 let url = req.url.split_once("?");
670 let url = match url {
671 Some((url, _)) => url,
672 None => req.url,
673 };
674 let key = format!("{}{}", req.method, url);
675 //println!("{key}");
676 match router.get(&key) {
677 Some(result) => {
678 invoke_router(result, req, res);
679 }
680 None => {
681 // may be wildcard
682 let r = router.keys().find(|&k| -> bool {
683 let last = k.len() - 1;
684 if &k[last..] == "*" {
685 if key.len() > last - 1 {
686 if &k[..last - 1] == &key[..last - 1] {
687 true
688 } else {
689 false
690 }
691 } else {
692 false
693 }
694 } else {
695 false
696 }
697 });
698 match r {
699 Some(k) => {
700 let wild_router = router.get(k).unwrap(); // guaranteed by above
701 invoke_router(wild_router, req, res);
702 }
703 None => {
704 let not_found = router.get("NEVER_FOUND_FOR_ALL").unwrap(); // guaranteed
705 not_found.1.call(req, res);
706 }
707 }
708 // match router.get(&key) {
709 // Some(result) => {
710 // invoke_router(result, req, res);
711 // }
712 // None => {
713 // // actually have not this router
714 // let not_found = router.get("NEVER_FOUND_FOR_ALL").unwrap();
715 // not_found.1.call(req, res);
716 // }
717 // }
718 }
719 }
720}
721
722fn read_body<'a, 'b, 'c>(
723 stream: &mut TcpStream,
724 head_map: &HashMap<&'a str, &'b str>,
725 body: &'c mut Vec<u8>,
726 len: usize,
727 server_config: &ServerConfig,
728) -> BodyContent<'c> {
729 if len > 0 {
730 let body_type_key = head_map.keys().find(|&&k| -> bool {
731 if k.to_lowercase() == "content-type" {
732 return true;
733 }
734 false
735 });
736 match body_type_key {
737 Some(&body_type_key) => {
738 let &body_type = head_map.get(body_type_key).unwrap(); // guaranteed by above
739 // the body content from when reading head
740 let has_read_len = body.len();
741 if len > has_read_len {
742 // need to read out the remainder body content
743 let remainder = len - has_read_len;
744 //println!("neee size, {}", remainder);
745 //println!("need to read out the remainder body content");
746 return read_body_according_to_type(
747 stream,
748 body_type,
749 body,
750 remainder,
751 server_config,
752 );
753 } else {
754 // body has completely read out when reading head
755 //println!("body has completely read out when reading head");
756 return read_body_according_to_type(stream, body_type, body, 0, server_config);
757 }
758 }
759 None => {
760 //invalid body
761 return BodyContent::Bad;
762 }
763 }
764 } else {
765 return BodyContent::None;
766 }
767}
768
769// fn has_crlf(slice: &[u8]) -> Option<usize> {
770// let crlf = b"\r\n\r\n";
771// let pos = slice.windows(crlf.len()).position(|window| window == crlf);
772// pos
773// }
774
775fn read_body_according_to_type<'a>(
776 stream: &mut TcpStream,
777 body_type: &str,
778 container: &'a mut Vec<u8>,
779 mut need_read_size: usize,
780 server_config: &ServerConfig,
781) -> BodyContent<'a> {
782 //println!("raw:{body_type}");
783 let tp = body_type.to_lowercase();
784 if !tp.contains("multipart/form-data") {
785 if need_read_size != 0 {
786 //let mut buf: [u8; 1024] = [b'\0'; 1024];
787 let len = container.len();
788 //println!("alread read size {}",len);
789 let total_len = len + need_read_size;
790
791 if total_len > server_config.max_body_size {
792 return BodyContent::TooLarge;
793 }
794 container.resize(total_len, b'\0');
795 let mut start_pos = len;
796 loop {
797 match stream.read(&mut container[start_pos..]) {
798 Ok(read_size) => {
799 if read_size == 0 {
800 return BodyContent::Bad;
801 }
802 //println!("read size is:{}",read_size);
803 need_read_size -= read_size;
804 start_pos += read_size;
805 }
806 Err(_) => {
807 return BodyContent::Bad;
808 }
809 }
810 //println!("{}",need_read_size);
811 if need_read_size == 0 {
812 break;
813 }
814 }
815 }
816 if tp != "application/x-www-form-urlencoded" {
817 match std::str::from_utf8(&container[..]) {
818 Ok(s) => {
819 return BodyContent::PureText(s);
820 }
821 Err(_) => {
822 return BodyContent::Bad;
823 }
824 }
825 } else {
826 return parse_url_form_body(container);
827 }
828 } else {
829 // parse multiple form data
830 let split = body_type.split_once(";");
831 match split {
832 Some((_, boundary)) => match boundary.trim().split_once("=") {
833 Some((_, boundary)) => {
834 let boundary = format!("--{}", boundary.trim());
835 //println!("boundary: {}", boundary);
836 let end_boundary = format!("{}--", &boundary);
837 //println!("end boundary {}",end_boundary);
838 if container.len() == 0 {
839 //读头时没有读到body
840 let divider_len = boundary.len() + 2; // include --Boundary\r\n
841 container.resize(divider_len, b'\0');
842 match stream.read_exact(container) {
843 Ok(_) => {
844 need_read_size -= divider_len;
845 }
846 Err(e) => {
847 if server_config.open_log {
848 let now = get_current_date();
849 println!(
850 "[{}] >>> error in read_body_according_to_type in http_parser.rs; type: [{}], line: [{}], msg: [{}]",
851 now,
852 e.kind().to_string(),
853 line!(),
854 ToString::to_string(&e)
855 );
856 }
857 return BodyContent::Bad;
858 }
859 }
860 }
861 let r = read_multiple_form_body(
862 stream,
863 container,
864 (&boundary, &end_boundary),
865 need_read_size,
866 server_config,
867 );
868 match r {
869 Ok(form) => {
870 return BodyContent::Multi(form);
871 }
872 Err(e) => {
873 if server_config.open_log {
874 let now = get_current_date();
875 println!("[{}] >>> error in read_multiple_form_body in http_parser.rs; type: [{}], {}", now, e.kind().to_string(), ToString::to_string(&e));
876 }
877 return BodyContent::Bad;
878 }
879 }
880 }
881 None => return BodyContent::Bad,
882 },
883 None => return BodyContent::Bad,
884 }
885 };
886}
887
888fn parse_url_form_body(container: &mut Vec<u8>) -> BodyContent<'_> {
889 match std::str::from_utf8(&container[..]) {
890 Ok(s) => {
891 let t: HashMap<&str, &str> = s
892 .split("&")
893 .map(|x| match x.split_once("=").map(|(a, b)| (a, b)) {
894 Some((k, v)) => (k, v),
895 None => ("", ""),
896 })
897 .filter(|(k, v)| {
898 if k.len() == 0 || v.len() == 0 {
899 false
900 } else {
901 true
902 }
903 })
904 .collect();
905 return BodyContent::UrlForm(t);
906 }
907 Err(_) => {
908 return BodyContent::Bad;
909 }
910 }
911}
912
913#[derive(Debug)]
914struct FindSet {
915 find_pos: i64,
916 end_pos: usize,
917}
918
919fn find_substr<'a>(slice: &'a [u8], sub: &'a [u8], start: usize) -> FindSet {
920 match slice[start..]
921 .windows(sub.len())
922 .position(|binaray| binaray == sub)
923 {
924 Some(pos) => {
925 let include_pos = (start + pos) as i64;
926 FindSet {
927 find_pos: include_pos,
928 end_pos: include_pos as usize + sub.len(),
929 }
930 }
931 None => FindSet {
932 find_pos: -1,
933 end_pos: 0,
934 },
935 }
936}
937
938fn find_substr_once(slice: &[u8], sub: &[u8], start: usize) -> FindSet {
939 let remainder = slice.len() - start;
940 if sub.len() > remainder {
941 FindSet {
942 find_pos: -1,
943 end_pos: 0,
944 }
945 } else {
946 let end_pos = start + sub.len();
947 let compare_str = &slice[start..end_pos];
948 if compare_str == sub {
949 FindSet {
950 find_pos: start as i64,
951 end_pos: end_pos,
952 }
953 } else {
954 FindSet {
955 find_pos: -1,
956 end_pos: 0,
957 }
958 }
959 }
960}
961
962fn is_file(slice: &[u8]) -> bool {
963 let key = "filename=\"".as_bytes();
964 match slice.windows(key.len()).position(|x| x == key) {
965 Some(_) => true,
966 None => false,
967 }
968}
969
970fn parse_file_content_type(slice: &[u8]) -> (&str, &str) {
971 let end = slice.len() - 4;
972 let s = std::str::from_utf8(&slice[..end]).unwrap_or_else(|_| "");
973 match s.split_once(":") {
974 Some((k, v)) => {
975 return (k, v.trim());
976 }
977 None => return ("", ""),
978 }
979}
980
981fn get_file_extension(s: &str) -> &str {
982 match s.rfind(".") {
983 Some(x) => &s[x..],
984 None => "",
985 }
986}
987
988fn get_config_from_disposition(s: &str, is_file: bool) -> (Option<String>, Option<String>) {
989 let name = "name=\"";
990 let r = match s.find(name) {
991 Some(pos) => {
992 let pos = pos + name.len();
993 let name_end = "\"";
994 match s[pos..].find(name_end) {
995 Some(pos_end) => (Some(String::from(&s[pos..pos + pos_end])), pos_end),
996 None => (None, 0),
997 }
998 }
999 None => (None, 0),
1000 };
1001 if is_file {
1002 let file_name_key = "filename=\"";
1003 let bias = r.1 + 2;
1004 match s[bias..].find(file_name_key) {
1005 Some(pos) => {
1006 let pos = bias + pos + file_name_key.len();
1007 let end = "\"";
1008 match s[pos..].find(end) {
1009 Some(end) => {
1010 return (r.0, Some(String::from(&s[pos..pos + end])));
1011 }
1012 None => {
1013 return (r.0, None);
1014 }
1015 }
1016 }
1017 None => {
1018 return (r.0, None);
1019 }
1020 };
1021 }
1022 return (r.0, None);
1023}
1024
1025fn contains_substr(
1026 stream: &mut TcpStream,
1027 need_size: &mut usize,
1028 body_slice: &mut Vec<u8>,
1029 pat: &[u8],
1030 start: usize,
1031 line_number: u32,
1032) -> io::Result<FindSet> {
1033 let slice_len = body_slice.len();
1034 let pat_len = pat.len();
1035
1036 let find = find_substr(body_slice, &pat[..1], start); // abcde 先测试a的位置
1037 if find.find_pos != -1 {
1038 let pos = find.find_pos as usize;
1039
1040 let sub_str_len = slice_len - pos;
1041
1042 if sub_str_len >= pat_len {
1043 let sub_slice = &body_slice[pos..pos + pat_len]; //获取找到位置,到pat的长度的slice
1044 if sub_slice == pat {
1045 //body_slice中有pat的子序列
1046 return io::Result::Ok(FindSet {
1047 find_pos: pos as i64,
1048 end_pos: pos + pat_len,
1049 });
1050 }
1051 return io::Result::Ok(FindSet {
1052 find_pos: -1,
1053 end_pos: 0,
1054 });
1055 } else {
1056 // 长度不够用来比较, 再读取需要的字节拼接起来进行比较
1057 let need = pat_len - sub_str_len;
1058 //let may_sub_slice = &body_slice[pos..];
1059 let start_read_pos = body_slice.len();
1060 body_slice.resize(start_read_pos + need, b'\0');
1061 //let mut buff = vec![b'\0'; need];
1062
1063 match stream.read_exact(&mut body_slice[start_read_pos..]) {
1064 Ok(_) => {
1065 *need_size -= need;
1066 // let mut complete = Vec::new();
1067 // complete.extend_from_slice(may_sub_slice);
1068 // complete.extend_from_slice(&buff);
1069 //body_slice.extend_from_slice(&buff);
1070 if &body_slice[pos..pos + need] == pat {
1071 //读取可以比较的数据后,比较结果包含pat
1072 return io::Result::Ok(FindSet {
1073 find_pos: pos as i64,
1074 end_pos: pos + pat_len,
1075 });
1076 } else {
1077 return io::Result::Ok(FindSet {
1078 find_pos: -1,
1079 end_pos: 0,
1080 });
1081 }
1082 }
1083 Err(e) => {
1084 let msg = format!("line: [{}], msg: [{}]", line_number, e.to_string());
1085 return io::Result::Err(io::Error::new(e.kind(), msg));
1086 }
1087 }
1088 }
1089 }
1090 return io::Result::Ok(FindSet {
1091 find_pos: -1,
1092 end_pos: 0,
1093 });
1094}
1095
1096fn read_multiple_form_body<'a>(
1097 stream: &mut TcpStream,
1098 body: &'a mut Vec<u8>,
1099 (boundary, end): (&String, &String),
1100 mut need_size: usize,
1101 server_config: &ServerConfig,
1102) -> io::Result<HashMap<String, MultipleFormData<'a>>> {
1103 let mut state = 0;
1104 let mut buffs = Vec::new();
1105 buffs.extend_from_slice(body);
1106 let crlf_sequence = b"\r\n";
1107 let boundary_sequence = boundary.as_bytes();
1108 let mut text_only_sequence = Vec::new();
1109 let mut end_boundary_sequence = Vec::new();
1110 end_boundary_sequence.extend_from_slice(end.as_bytes());
1111 //end_boundary_sequence.extend_from_slice(b"\r\n");
1112
1113 let end_boundary_sequence = end_boundary_sequence;
1114
1115 let mut crlf_boundary_sequence = Vec::new();
1116 crlf_boundary_sequence.push(b'\r');
1117 crlf_boundary_sequence.push(b'\n');
1118 crlf_boundary_sequence.extend_from_slice(boundary_sequence);
1119 let crlf_boundary_sequence = crlf_boundary_sequence;
1120
1121 let mut multiple_data_collection: HashMap<String, MultipleFormData> = HashMap::new();
1122
1123 'Outer: loop {
1124 match state {
1125 0 => {
1126 // 找boundary
1127 // 当前状态,buffs的内容总是以--Boundary??开头
1128 let r = contains_substr(
1129 stream,
1130 &mut need_size,
1131 &mut buffs,
1132 boundary_sequence,
1133 0,
1134 line!(),
1135 )?; // 确保找到boundary_sequence
1136
1137 if r.find_pos != -1 {
1138 let mut subsequent = Vec::new();
1139 let start = r.end_pos as usize + 2; //--Boundary?? 跳过?? 有可能是\r\n
1140 if start > buffs.len() {
1141 let mut buff_two = [b'\0'; 2];
1142 match stream.read_exact(&mut buff_two) {
1143 Ok(_) => {
1144 need_size -= 2;
1145 buffs.extend_from_slice(&buff_two);
1146 }
1147 Err(e) => {
1148 let msg = format!("line: [{}], msg: [{}]", line!(), e.to_string());
1149 return Err(io::Error::new(e.kind(), msg));
1150 }
1151 }
1152 }
1153
1154 let is_end = find_substr_once(&buffs, &end_boundary_sequence, 0);
1155
1156 if is_end.find_pos == r.find_pos {
1157 //确定是否是完全结束的分隔符,如果对--Boundary 和--Boundary--分别进行查找,如果他们起始位置一致,那么就是结尾符
1158 break 'Outer;
1159 }
1160 subsequent.extend_from_slice(&buffs[start..]);
1161 buffs = subsequent;
1162 state = 1;
1163 continue 'Outer;
1164 } else {
1165 let msg = format!("line: [{}], msg: [bad body]", line!());
1166 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
1167 }
1168 }
1169 1 => {
1170 // Content-disposition:...\r\n
1171
1172 let mut r = FindSet {
1173 find_pos: -1,
1174 end_pos: 0,
1175 };
1176 while r.find_pos == -1 {
1177 r = contains_substr(
1178 stream,
1179 &mut need_size,
1180 &mut buffs,
1181 crlf_sequence,
1182 0,
1183 line!(),
1184 )?; // 通过找\r\n
1185 if r.find_pos == -1 {
1186 //let mut buff = [b'\0'; 256];
1187 let start_read_pos = buffs.len();
1188 buffs.resize(
1189 start_read_pos + server_config.read_buff_increase_size,
1190 b'\0',
1191 );
1192 match stream.read(&mut buffs[start_read_pos..]) {
1193 Ok(size) => {
1194 if size == 0 {
1195 let info =
1196 format!("line: [{}], msg: [lost connection]", line!());
1197 let e = io::Error::new(io::ErrorKind::InvalidInput, info);
1198 return io::Result::Err(e);
1199 }
1200 need_size -= size;
1201 buffs.resize(start_read_pos + size, b'\0');
1202 }
1203 Err(e) => {
1204 let msg = format!("line: [{}], msg: [{}]", line!(), e.to_string());
1205 return Err(io::Error::new(e.kind(), msg));
1206 }
1207 };
1208 }
1209 }
1210
1211 if r.find_pos != -1 {
1212 let content_disposition_end = r.end_pos;
1213 let content_disposition = &buffs[..content_disposition_end];
1214
1215 if !is_file(content_disposition) {
1216 //println!("是文本内容");
1217 // 是文本内容
1218
1219 let mut subsequent = Vec::new();
1220 text_only_sequence.extend_from_slice(boundary_sequence);
1221 text_only_sequence.extend_from_slice(b"\r\n");
1222 text_only_sequence.extend_from_slice(content_disposition);
1223
1224 subsequent.extend_from_slice(&buffs[content_disposition_end..]); // 移除content_disposition的内容
1225 buffs = subsequent;
1226
1227 let mut find_boundary = FindSet {
1228 find_pos: -1,
1229 end_pos: 0,
1230 };
1231
1232 while find_boundary.find_pos == -1 {
1233 find_boundary = contains_substr(
1234 stream,
1235 &mut need_size,
1236 &mut buffs,
1237 boundary_sequence,
1238 0,
1239 line!(),
1240 )?;
1241 if find_boundary.find_pos == -1 {
1242 //let mut buff = [b'\0'; 256];
1243 let start_read_pos = buffs.len();
1244 buffs.resize(
1245 start_read_pos + server_config.read_buff_increase_size,
1246 b'\0',
1247 );
1248 match stream.read(&mut buffs[start_read_pos..]) {
1249 Ok(size) => {
1250 if size == 0 {
1251 let info = format!(
1252 "line: [{}], msg: [lost connection]",
1253 line!()
1254 );
1255 let e =
1256 io::Error::new(io::ErrorKind::InvalidInput, info);
1257 return io::Result::Err(e);
1258 }
1259 //buffs.extend_from_slice(&buff[..size]);
1260 buffs.resize(start_read_pos + size, b'\0');
1261 need_size -= size;
1262 }
1263 Err(e) => {
1264 let msg = format!(
1265 "line: [{}], msg: [{}]",
1266 line!(),
1267 e.to_string()
1268 );
1269 return Err(io::Error::new(e.kind(), msg));
1270 }
1271 };
1272 }
1273 }
1274 if find_boundary.find_pos != -1 {
1275 let start = find_boundary.find_pos as usize;
1276 let text_slice = &buffs[..start];
1277 text_only_sequence.extend_from_slice(text_slice);
1278
1279 let mut subsequent = Vec::new();
1280 subsequent.extend_from_slice(&buffs[start..]);
1281
1282 buffs = subsequent;
1283 state = 0;
1284 continue 'Outer;
1285 }
1286 } else {
1287 //文件
1288 let s = {
1289 match std::str::from_utf8(content_disposition) {
1290 Ok(x) => x,
1291 Err(e) => {
1292 let msg =
1293 format!("line: [{}], msg: [{}]", line!(), e.to_string());
1294 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
1295 }
1296 }
1297 };
1298 let config = get_config_from_disposition(s, true);
1299 let indice_name = match config.0 {
1300 Some(x) => x,
1301 None => {
1302 let msg = format!(
1303 "line: [{}], msg: [cannot get indice name from requested body]",
1304 line!()
1305 );
1306 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
1307 }
1308 };
1309 let filename = match config.1 {
1310 Some(x) => x,
1311 None => {
1312 let msg = format!(
1313 "line: [{}], msg: [cannot get file indice from requested body]",
1314 line!()
1315 );
1316 return Err(io::Error::new(io::ErrorKind::InvalidData, msg));
1317 }
1318 };
1319 let uid = uuid::Uuid::new_v4().to_string();
1320 let extension = get_file_extension(&filename);
1321 let filepath =
1322 format!("{}/{}{}", &server_config.upload_directory, uid, extension);
1323 let mut file = MultipleFormFile {
1324 filename: filename,
1325 filepath: filepath,
1326 content_type: String::new(),
1327 form_indice: indice_name,
1328 };
1329
1330 let mut subsequent = Vec::new();
1331 subsequent.extend_from_slice(&buffs[content_disposition_end..]); // 移除content_disposition的内容
1332 buffs = subsequent;
1333 let double_crlf = b"\r\n\r\n";
1334
1335 let mut find_double_crlf = FindSet {
1336 find_pos: -1,
1337 end_pos: 0,
1338 };
1339 while find_double_crlf.find_pos == -1 {
1340 find_double_crlf = contains_substr(
1341 stream,
1342 &mut need_size,
1343 &mut buffs,
1344 double_crlf,
1345 0,
1346 line!(),
1347 )?;
1348 if find_double_crlf.find_pos == -1 {
1349 //let mut buff = [b'\0'; 256];
1350 let start_read_pos = buffs.len();
1351 buffs.resize(
1352 start_read_pos + server_config.read_buff_increase_size,
1353 b'\0',
1354 );
1355 match stream.read(&mut buffs[start_read_pos..]) {
1356 Ok(size) => {
1357 if size == 0 {
1358 let info = format!(
1359 "line: [{}], msg: [lost connection]",
1360 line!()
1361 );
1362 let e =
1363 io::Error::new(io::ErrorKind::InvalidInput, info);
1364 return io::Result::Err(e);
1365 }
1366 //buffs.extend_from_slice(&buff[..size]);
1367 buffs.resize(start_read_pos + size, b'\0');
1368 need_size -= size;
1369 }
1370 Err(e) => {
1371 let info = format!(
1372 "line: [{}], msg: [{}]",
1373 line!(),
1374 e.to_string()
1375 );
1376 let e = io::Error::new(e.kind(), info);
1377 return io::Result::Err(e);
1378 }
1379 };
1380 }
1381 }
1382
1383 if find_double_crlf.find_pos != -1 {
1384 // Content-type:...\r\n\r\n
1385 let content_type = &buffs[..find_double_crlf.end_pos];
1386 let result = parse_file_content_type(&content_type);
1387 file.content_type = result.1.to_string();
1388 let mut subsequent = Vec::new();
1389 subsequent.extend_from_slice(&buffs[find_double_crlf.end_pos..]); // 移除content-type:...\r\n\r\n
1390 buffs = subsequent;
1391
1392 let mut file_handle = match OpenOptions::new()
1393 .write(true)
1394 .create(true)
1395 .open(file.filepath.clone())
1396 {
1397 Ok(file) => file,
1398 Err(e) => {
1399 let msg =
1400 format!("line: [{}], msg: [{}]", line!(), e.to_string());
1401 return Err(io::Error::new(e.kind(), msg));
1402 }
1403 };
1404
1405 let file_path = file.filepath.clone();
1406 multiple_data_collection
1407 .insert(file.form_indice.clone(), MultipleFormData::File(file));
1408
1409 let mut find_cr;
1410
1411 //let mut file_buff = [b'\0'; 1024];
1412 loop {
1413 find_cr = find_substr(&buffs, b"\r", 0);
1414 //以\r为关键字判断是否是文件内容的一部分还是分隔符的一部分
1415 if find_cr.find_pos == -1 {
1416 //如果整个字节串里没有\r, 那么一定都是文件内容
1417 match file_handle.write(&buffs) {
1418 Ok(_) => {}
1419 Err(e) => {
1420 let msg = format!(
1421 "line: [{}], msg: [{}]",
1422 line!(),
1423 e.to_string()
1424 );
1425 return Err(io::Error::new(e.kind(), msg));
1426 }
1427 };
1428 //buffs.clear();
1429 buffs.resize(server_config.read_buff_increase_size, b'\0');
1430 match stream.read(&mut buffs[0..]) {
1431 Ok(size) => {
1432 if size == 0 {
1433 let info = format!(
1434 "line: [{}], msg: [lost connection]",
1435 line!()
1436 );
1437 let e = io::Error::new(
1438 io::ErrorKind::InvalidInput,
1439 info,
1440 );
1441 drop(file_handle);
1442 let _ = std::fs::remove_file(file_path);
1443 return io::Result::Err(e);
1444 }
1445 need_size -= size;
1446 buffs.resize(size, b'\0');
1447 //buffs.clear();
1448 //buffs.extend_from_slice(&file_buff[..size]);
1449 }
1450 Err(e) => {
1451 drop(file_handle);
1452 let _ = std::fs::remove_file(file_path);
1453 let msg = format!(
1454 "line: [{}], msg: [{}]",
1455 line!(),
1456 e.to_string()
1457 );
1458 return Err(io::Error::new(e.kind(), msg));
1459 }
1460 }
1461 } else {
1462 let pos = find_cr.find_pos as usize;
1463 let len = buffs.len();
1464 if pos + 1 < len {
1465 let u = buffs[pos + 1];
1466 if u == b'\n' {
1467 //判断\r下一个字节是否是\n
1468 let compare_len = len - pos;
1469 if compare_len >= crlf_boundary_sequence.len() {
1470 //剩余大小足够比较\r\n是否属于分隔符
1471 let find_test = find_substr_once(
1472 &buffs,
1473 &crlf_boundary_sequence,
1474 pos,
1475 );
1476 if find_test.find_pos != -1 {
1477 //如果\r\n是分隔符
1478 match file_handle.write(&buffs[0..pos]) {
1479 Ok(_) => {}
1480 Err(e) => {
1481 let msg = format!(
1482 "line: [{}], msg: [{}]",
1483 line!(),
1484 e.to_string()
1485 );
1486 drop(file_handle);
1487 let _ = std::fs::remove_file(file_path);
1488 return Err(io::Error::new(
1489 e.kind(),
1490 msg,
1491 ));
1492 }
1493 };
1494 state = 0;
1495 let mut temp = Vec::new();
1496 temp.extend_from_slice(&buffs[pos + 2..]); //找\r\n--Boundary, 跳过\r\n
1497 buffs = temp;
1498 continue 'Outer;
1499 } else {
1500 //\r\n不是形成分隔符的关键字,那么他们就是文件内容的一部分
1501 match file_handle.write(&buffs[0..=pos + 1]) {
1502 Ok(_) => {}
1503 Err(e) => {
1504 let msg = format!(
1505 "line: [{}], msg: [{}]",
1506 line!(),
1507 e.to_string()
1508 );
1509 drop(file_handle);
1510 let _ = std::fs::remove_file(file_path);
1511 return Err(io::Error::new(
1512 e.kind(),
1513 msg,
1514 ));
1515 }
1516 };
1517 let mut temp = Vec::new();
1518 temp.extend_from_slice(&buffs[pos + 2..]);
1519 buffs = temp;
1520 continue;
1521 }
1522 } else {
1523 //如果关键字是\r\n, 但后续没有足够能够进行比较的字节
1524
1525 //let mut need_buff = vec![b'\0'; 1024];
1526 let start_read_pos = buffs.len();
1527 buffs.resize(
1528 start_read_pos
1529 + server_config.read_buff_increase_size,
1530 b'\0',
1531 );
1532 match stream.read(&mut buffs[start_read_pos..]) {
1533 //继续读一部分内容以进行拼凑比较
1534 Ok(size) => {
1535 if size == 0 {
1536 let info = format!("line: [{}], msg: [lost connection]",line!());
1537 let e = io::Error::new(
1538 io::ErrorKind::InvalidInput,
1539 info,
1540 );
1541 drop(file_handle);
1542 let _ = std::fs::remove_file(file_path);
1543 return io::Result::Err(e);
1544 }
1545 need_size -= size;
1546 buffs.resize(start_read_pos + size, b'\0');
1547 //buffs.extend_from_slice(&need_buff[..size]);
1548 let r = find_substr_once(
1549 &buffs,
1550 &crlf_boundary_sequence,
1551 pos,
1552 );
1553 if r.find_pos != -1 {
1554 //拼凑后\r\n形成了分隔符
1555 let pos = r.find_pos as usize;
1556 match file_handle.write(&buffs[0..pos])
1557 {
1558 Ok(_) => {}
1559 Err(e) => {
1560 let msg = format!(
1561 "line: [{}], msg: [{}]",
1562 line!(),
1563 e.to_string()
1564 );
1565 drop(file_handle);
1566 let _ = std::fs::remove_file(
1567 file_path,
1568 );
1569 return Err(io::Error::new(
1570 e.kind(),
1571 msg,
1572 ));
1573 }
1574 };
1575 state = 0;
1576 let mut temp = Vec::new();
1577 temp.extend_from_slice(
1578 &buffs[pos + 2..],
1579 ); //找\r\n--Boundary, 跳过\r\n
1580 buffs = temp;
1581 continue 'Outer;
1582 } else {
1583 //拼凑后发现\r\n不是形成分隔符的关键字,那么\r\n就是文件内容的一部分
1584 match file_handle
1585 .write(&buffs[0..=pos + 1])
1586 {
1587 Ok(_) => {}
1588 Err(e) => {
1589 let msg = format!(
1590 "line: [{}], msg: [{}]",
1591 line!(),
1592 e.to_string()
1593 );
1594 drop(file_handle);
1595 let _ = std::fs::remove_file(
1596 file_path,
1597 );
1598 return Err(io::Error::new(
1599 e.kind(),
1600 msg,
1601 ));
1602 }
1603 };
1604 let mut temp = Vec::new();
1605 //\r\n是文件内容,所以从\n后面开始
1606 temp.extend_from_slice(
1607 &buffs[pos + 2..],
1608 );
1609 buffs = temp;
1610 continue;
1611 }
1612 }
1613 Err(e) => {
1614 drop(file_handle);
1615 let _ = std::fs::remove_file(file_path);
1616 let msg = format!(
1617 "line: [{}], msg: [{}]",
1618 line!(),
1619 e.to_string()
1620 );
1621 return Err(io::Error::new(e.kind(), msg));
1622 }
1623 }
1624 }
1625 } else {
1626 //\r的下一个字节不是\n, 那么可以肯定\r是文件的内容
1627 match file_handle.write(&buffs[0..=pos]) {
1628 Ok(_) => {}
1629 Err(e) => {
1630 let msg = format!(
1631 "line: [{}], msg: [{}]",
1632 line!(),
1633 e.to_string()
1634 );
1635 drop(file_handle);
1636 let _ = std::fs::remove_file(file_path);
1637 return Err(io::Error::new(e.kind(), msg));
1638 }
1639 };
1640 let mut temp = Vec::new();
1641 temp.extend_from_slice(&buffs[pos + 1..]); //从\r的下一个字节开始
1642 buffs = temp;
1643 continue;
1644 }
1645 } else {
1646 // \r正好是buffs里面的最后一个字节,那么只能确定0~前一个字节是文件内容
1647 match file_handle.write(&buffs[0..pos]) {
1648 Ok(_) => {}
1649 Err(e) => {
1650 let msg = format!(
1651 "line: [{}], msg: [{}]",
1652 line!(),
1653 e.to_string()
1654 );
1655 drop(file_handle);
1656 let _ = std::fs::remove_file(file_path);
1657 return Err(io::Error::new(e.kind(), msg));
1658 }
1659 };
1660 //buffs.clear();
1661 buffs.resize(server_config.read_buff_increase_size, b'\0');
1662 buffs[0] = b'\r';
1663
1664 //let mut temp_buff = [b'\0'; 1024];
1665 match stream.read(&mut buffs[1..]) {
1666 Ok(size) => {
1667 if size == 0 {
1668 let info = format!(
1669 "line: [{}], msg: [lost connection]",
1670 line!()
1671 );
1672 let e = io::Error::new(
1673 io::ErrorKind::InvalidInput,
1674 info,
1675 );
1676 drop(file_handle);
1677 let _ = std::fs::remove_file(file_path);
1678 return io::Result::Err(e);
1679 }
1680 //let mut temp = Vec::new();
1681 //temp.extend_from_slice(&buffs[pos..]);
1682 need_size -= size;
1683 buffs.resize(1 + size, b'\0');
1684 //temp.extend_from_slice(&temp_buff[..size]);
1685 //buffs = temp;
1686 continue;
1687 }
1688 Err(e) => {
1689 drop(file_handle);
1690 let _ = std::fs::remove_file(file_path);
1691 let msg = format!(
1692 "line: [{}], msg: [{}]",
1693 line!(),
1694 e.to_string()
1695 );
1696 return Err(io::Error::new(e.kind(), msg));
1697 }
1698 }
1699 }
1700 }
1701 }
1702 }
1703 }
1704 }
1705 }
1706 _ => {}
1707 }
1708 }
1709 if need_size != 0 {
1710 let mut buff = [b'\0'; 10]; //充其量没有之前的循环中没有读 --end_boundary--?? ??两个字节
1711 match stream.read(&mut buff) {
1712 Ok(_) => {}
1713 Err(e) => {
1714 let msg = format!("line: [{}], msg: [{}]", line!(), e.to_string());
1715 return Err(io::Error::new(e.kind(), msg));
1716 }
1717 }
1718 }
1719
1720 body.clear();
1721 body.extend_from_slice(&text_only_sequence);
1722 let mut pat = Vec::new();
1723 pat.extend_from_slice(&boundary_sequence);
1724 pat.extend_from_slice(b"\r\n");
1725
1726 match std::str::from_utf8(&pat) {
1727 Ok(pat) => match std::str::from_utf8(body) {
1728 Ok(s) => {
1729 for el in s.split(pat) {
1730 if el == "" {
1731 continue;
1732 }
1733 let r = el.split_once("\r\n\r\n");
1734 //let r = r.unwrap();
1735 match r {
1736 Some(r) => {
1737 let name = get_config_from_disposition(r.0, false);
1738 let indice_name = match name.0 {
1739 Some(x) => x,
1740 None => {
1741 let msg = format!("line: [{}], msg: [cannot get indice name from requested body]", line!());
1742 return io::Result::Err(io::Error::new(
1743 io::ErrorKind::InvalidData,
1744 msg,
1745 ));
1746 }
1747 };
1748 let text_len = r.1.len();
1749 multiple_data_collection
1750 .insert(indice_name, MultipleFormData::Text(&r.1[0..text_len - 2]));
1751 //处理文本时, 包含了分隔符的\r\n,在这里去除
1752 }
1753 None => {
1754 let msg = format!(
1755 "line: [{}], msg: [bad body with unknown format multipart form]",
1756 line!()
1757 );
1758 let e = io::Error::new(ErrorKind::InvalidData, msg);
1759 return io::Result::Err(e);
1760 }
1761 }
1762 }
1763 return io::Result::Ok(multiple_data_collection);
1764 }
1765 Err(_) => {
1766 let msg = format!("line: [{}], msg: [bad body with invalid utf8]", line!());
1767 let e = io::Error::new(ErrorKind::InvalidData, msg);
1768 return io::Result::Err(e);
1769 }
1770 },
1771 Err(_) => {
1772 let msg = format!("line: [{}], msg: [bad body with invalid utf8]", line!());
1773 let e = io::Error::new(ErrorKind::InvalidData, msg);
1774 return io::Result::Err(e);
1775 }
1776 }
1777}