#Force EOF on BufReaderer

50 messages · Page 1 of 1 (latest)

frozen jackal
#

hello people !! I'm just learning rust, and I was wondering how I can force EOF within BufReader without closing the TCP connection / what would be the best way of handling this situation? As it stands, when a user sends an http request to the server (snippet), the server doesn't start processing it until EOF (in this case, connection close). So the handle_request function gets fired off only when the connection is closed, resulting in its payload going to the void. I'm using std::io::BufReader

fn main() {
    println!("Logs from your program will appear here!");

    let listener = TcpListener::bind("127.0.0.1:4221").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {
                // let mut body = String::with_capacity(512);
                let mut body = String::default();
                println!("fuckckkkk");
                let mut buf = BufReader::new(&mut stream);
                println!("you digging in me king 😫");
                buf.read_to_string(&mut body).unwrap();
                let req = HttpRequest::from_string(&body);
                println!("parsed connection");
                handle_request(&mut stream, &req);
            }

            Err(e) => {
                println!("error: {}", e);
            }
        }
    }
}
#

oh I can't send images here

#

fuck my chud life

frozen jackal
#

please

young depot
#

im really confused on what is your idea for this code.

#

why are you passing the stream into handle request?

frozen jackal
#

im just doing codecrafters basic http server

young depot
#

Im just trying to understand what your intensions are with this so i can help

frozen jackal
#

because the handle_request writes to the tcp connection based on the endpoint that from the parsed req

#


fn handle_request(connection: &mut TcpStream, req: &HttpRequest) {
    println!("help");
    match req.path.as_str() {
        "/strawberry" => {
            _ = connection
                .write_all("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes())
                .unwrap()
        }
        _ => {
            connection
                .write_all("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes())
                .unwrap();
        }
    }
    println!("holp");
}


#

im a complete beginner so if this is not idiomatic im sorry

young depot
#

its much better if you had handle_request return the bytes and then write it in the match statement.

frozen jackal
#

noted !!

young depot
#

also you have a borrow checker error

frozen jackal
#

do I?

young depot
#

let mut buf = BufReader::new(&mut stream);

frozen jackal
#

it compiles and runs ?

young depot
#

here you are passing in &mut stream

#

unless buf is dropped which it is not

#

im assuming those yes king print statements are appearing?

frozen jackal
#

nop

#

everything after let mut buf = BufReader::new(&mut stream); doesn't appear

#

until connection is dropped

young depot
#

why must you use buf-reader

frozen jackal
#

so particular reason, I saw this being commonly used in the solutions section, seemed elegant to whatever I was trying to do

young depot
#

im pretty sure http requests are sized so you can do a read_exact()

frozen jackal
#

is there a better approach for this?

frozen jackal
#

cause the HttpRequest thing I just implemented myself

young depot
#

Id do this:
use std::io::Read & std::io::Write
to read and write to the stream not a buf-reader.
read the contents into a buffer then pass them to the handler to be handled.
the handlers return will be written to the stream.

#

then are you sure you are pasrsing the http request correctly

#

you do know rust uses utf-8 by default not ascii

frozen jackal
young depot
#

the read() & write() metods are from their respective traits so that means the stream has a unique implementation for them like a interface.

#

so it will know when a tcp packet ends

#

( im pretty sure ive only worked with tokio tcp listeners )

young depot
#

Read offers no guarantees since its abstract.

#

But in the case of TcpStream a tcp package has a end, which it can understand since its a TcpStream not a BufReader.

#

BufReader is good for files since they always have a guaranteed size.

frozen jackal
#

maybe i am highly mentally incapacitated (highly probable)

#

but ts is reading a whole of 0 (zero) bytes !!

#
fn main() {
    println!("Logs from your program will appear here!");

    let listener = TcpListener::bind("127.0.0.1:4221").unwrap();

    for stream in listener.incoming() {
        match stream {
            Ok(mut stream) => {

                let mut body = String::default();
                println!("fuckckkkk");
                let mut buf = vec![];
                let mut parsed = stream.read(&mut buf).unwrap();
                println!("you digging in me king :tired_face:");
                dbg!(parsed);
                dbg!(buf);
            }

            Err(e) => {
                println!("error: {}", e);
            }
        }
    }
}

#

what am I doing wrong

#

fyi the request that im making is literally just curl -v http://localhost:4221/abcdefg

#

but I'd suppose it would have at least some sort of data attached to it?

#

Force EOF on BufReaderer (free pawjob for help)

craggy berry
#

your username, that message, and the forum title are inappropriate, and I'd appreciate if you changed them