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}