2

This is more to understand how things are working so please don't suggest using an HTTP lib.

I have the following code

use tokio::net::{TcpListener, TcpStream};

use std::error::Error;

async fn process_socket(mut socket: TcpStream) {
    socket
        .write_all(b"HTTP/1.1 404
Content-Length: 0")
        .await
        .expect("failed to write data to socket");
    socket
        .flush()
        .await
        .expect("failed to flush socket");    
}

Per this question, it should be a valid minimum HTTP response. When I run and visit the page in the browser I get the following

enter image description here

Notice there is no status in the column and it seems to not recognize the message.

I have also tried safari which says...

"cannot parse response" (NSURLErrorDomain:-1017)

What am I missing?

The rest of the code is...

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let addr = "127.0.0.1:8080";
    let listener = TcpListener::bind(&addr).await?;
    println!("Listening on: {}", addr);
    loop{
        let (socket, _) = listener.accept().await?;
        tokio::spawn(async move {
            // In a loop, read data from the socket and write the data back.
            process_socket(socket).await; 
        });
    }
}
kmdreko
  • 42,554
  • 6
  • 57
  • 106
Jackie
  • 21,969
  • 32
  • 147
  • 289

1 Answers1

3

You are missing several \r\n separators. The headers must be separated by one such pair, and the response's header section must be terminated by two such pairs:

.write_all(b"HTTP/1.1 404\r\nContent-Length: 0\r\n\r\n")

From the spec

Response      = Status-Line               ; Section 6.1
                *(( general-header        ; Section 4.5
                 | response-header        ; Section 6.2
                 | entity-header ) CRLF)  ; Section 7.1
                CRLF
                [ message-body ]          ; Section 7.2
kmdreko
  • 42,554
  • 6
  • 57
  • 106
Svetlin Zarev
  • 14,713
  • 4
  • 53
  • 82
  • I thought it would infer the line breaks in Rust I didnt think this needed to be explicit. Is there a particular reason it is the case here? Also why are you using the windows version of line break? Thank you – Jackie Jun 19 '21 at 16:18
  • http://www.cs.toronto.edu/~krueger/csc209h/tut/line-endings.html – Jackie Jun 19 '21 at 16:19
  • 2
    The http spec requires CRLF. The line breaks in your file are OS & IDE dependent - for instance on my linux & mac boxes they are just LF. The Rust compiler cannot possibly know that this is a HTTP response body in order to automagically fix them – Svetlin Zarev Jun 19 '21 at 16:20
  • I didnt realize http required crlf thank you – Jackie Jun 19 '21 at 16:22