How to get content from TcpStream again?

What should i do to receive the message body from a post request?
I saw a lot of examples, but they read all the data into a array one time, but if the body is very big, i want to loop to read the data in to array,but it is failed, it never get any data anymore, why? The code is as below:

let mut buf_reader = BufReader::new(&mut stream);
            let mut is_header_body_split = false;
            let req_lines:Vec<_> = buf_reader.by_ref().lines()
                .map(|result| result.unwrap_or_else(|_| return "".to_string()))
                .take_while(|line| !line.is_empty() )
                .collect();

let mut http_request = HttpRequest::parse_request(req_lines);
            match http_request.method {
                Method::POST => {
                    if http_request.header.contains_key("Content-Length") {
                        let content_length_str= http_request.header.get("Content-Length").unwrap();
                        if content_length_str.is_empty() {
                            http_request.body = "".to_string();
                        } else {
                            let content_length = content_length_str.as_str().parse::<usize>().unwrap();

                            let mut buf ;
                            if content_length <=1024 {
                                buf = Vec::with_capacity(content_length);
                                let current_size= buf_reader.by_ref().read_exact(&mut buf).unwrap();
                                http_request.body = String::from_utf8(buf).unwrap();
                            }else {
                                buf = Vec::with_capacity(1024);
                                let mut body_buf = vec![0u8,0];
                                let mut size =0;
                                loop {
                                    if size>=content_length {
                                        break;
                                    }
                                    let current_size= stream.read(&mut buf).unwrap();
                                    size +=current_size;
                                    body_buf.append(&mut buf[..current_size].to_vec());
                                }
                                http_request.body = String::from_utf8(body_buf).unwrap();
                            }

                        }

                    } else {
                        //todo

                    }
                }
}

If you're dealing with very large data you should - if possible - stream-process it, i.e. only keep a small chunk of it in memory and process the data as it comes in.

If that's not possible you may want to persist it to disk and then operate on the data from disk.

Data in a TCP stream is only available once, you can't get it again after it has been consumed.

Data in a TCP stream is only available once, you can't get it again after it has been consumed.
If so, it must be consumed in this step even it doesn't consume it because of the !line.is_empty(), i think.

let req_lines:Vec<_> = buf_reader.by_ref().lines()
                .map(|result| result.unwrap_or_else(|_| return "".to_string()))
                .take_while(|line| !line.is_empty() )
                .collect();

Why so? It stops iterating over .lines() once BufReader returns the empty line, so everything not buffered yet stays in TcpStream, and everything buffered after the empty line stays in buffer.

  • so everything not buffered yet stays in TcpStream*

yes, if i stop the connection from UI, I can continue to get the post body message.
So i have another question, if i don't end the connection, it can not receive the post body, right?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.