I am writing an HTTP client for terminal, similar to curl, as a learning exercise.

There's one limitation it suffers from and that is that it won't return until the client closes the socket. I fixed this problem with a hack by setting the socket to timeout after 1 second, but I feel like there has to be a better way.

Here is my code, I've commented what I already tried.

const BUFLEN: usize = 1024;
const NEWLINE: &str = "\r\n";

fn send_http(_s: &String) -> String {
    let mut stream = TcpStream::connect(_s).unwrap();
    let _ = stream.write(b"GET / HTTP/1.1\r\n\r\n");
    let mut response = String::new();
    let mut read;
    // This is the line that fixed the problem.
    let res = stream.set_read_timeout(Some(Duration::new(1,0)));
    loop {
        read = [0; BUFLEN];
        let result = stream.read(&mut read);
        match result {
            Ok(n) => {
                let resp = String::from_utf8_lossy(&read).into_owned();
                print!("{}", resp);
                //here I tried this:
                //if n > 0 && n < 1024 { break; }
                //because if it reads any less than 1024,
                //that should be the last block it reads.
            } Err(err) => { return response }

fn main() {
    let addr = "www.yahoo.com:80";
    let addr_str = String::from(addr);
    print!("{}", send_http(&addr_str));

The if statement in the match arm does nothing. Like I said, the code works fine but it's been hacked together. Doesn't feel right. Suggestions?

  • \$\begingroup\$ Try reading from the stream until n == 0. \$\endgroup\$ – dfhwze Jun 7 '19 at 4:42
  • \$\begingroup\$ I have. It ends up just doing the same thing. \$\endgroup\$ – leaustinwile Jun 7 '19 at 4:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.