How to make a HTTP Get request with std

I'm currently trying to make an HTTP request only using STD but all the resources I've found are outdated and 6 years old!
I don't understand why this is not working! This server uses Cloudflare and I get a 400 bad Request error.
(If I use a local server on Actix everything is fine)

fn req() -> std::io::Result<String> {
    let host = "";
    let path = "/v3/api/a/b/c";

    let ip_lookup = host.to_socket_addrs()?.next().unwrap();

    println!("{:?}", ip_lookup);

    let mut socket = TcpStream::connect_timeout(&ip_lookup, Duration::from_millis(5000))?;

    let mut headers = HashMap::new();
    headers.insert("Host", host);

    let mut header = format!("GET {} HTTP/1.1\n{}\n\n",path,headers.iter().map(|(i,x)| format!("{}: {}",i,x)).collect::<Vec<_>>().join("\n"));

    let mut headers = String::new();
    socket.read_to_string(&mut headers)?;

We should get OK 200 with invalid as text but Cloudflare seems to be blocking the request for no apparent reason. (This request works from a Rest Client or Web Browser).

Thanks for your help;

The request would be malformed. HTTP headers must be separated with a CR LF (\r\n), not just \n.

If I use \r\n the request never ends and I don't know why

Do you also have a trailing \r\n\r\n? The server might be waiting for more input...

[quote="naim, post:4, topic:52496, full:true"]
Do you also have a trailing \r\n\r\n? The server might be waiting for more input...

The connection isn't closing since HTTP/1.1 allows multiple requests per connection. That's the reason read_to_string isn't returning.

Possible solutions:

  1. Use read and handle the response as it is received, without waiting for EOF.
  2. Use HTTP/1.0, which doesn't support keep-alive and will terminate the connection.
  3. Add the Connection: close header, which will have the same behaviour of HTTP/1.0.
1 Like

Thanks this is now working

1 Like

Thanks this is now working

Which option did you try, out of the three suggested?

The second one