Book: ch20-01-single-threaded.md - Response needs Content-Length header

Created on 19 Apr 2018  路  11Comments  路  Source: rust-lang/book

This affects 2nd edition and the 2018 edition:

The code samples for returning an HTTP response in this chapter appear to only work with liberal HTTP clients, but not browsers. For example, the first example where we're returning the contents of an HTML file (Listing 20-5) will work in CURL but if visited in a browser will fail to show the requested page.

All tests run under Ubuntu 17.10

CURL:
Works, shows the returned HTML, but warns: * no chunk, no close, no size. Assume close to signal end
Chrome:
DIsplays nothing, network tab shows: ERR_CONNECTION_RESET
Firefox:
DIsplays "The connection was reset", network tab indicates a 200 OK response, but no further data.

Altering the response line from:

let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);

...to....

let response = format!("HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", contents.len(), contents);

..results in the warning being removed from CURL, and the two browsers render the response HTML.

Enhancement

Most helpful comment

I can confirm that

let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);

threw net::ERR_CONNECTION_RESET 200 (OK) for me on chrome 74.0.3729.131 on Mac

Changing to include the content length fixed it.

All 11 comments

Hm, I had it working just fine with Firefox. That said, this is probably a good idea.

Hm, the code in listing 20-5 loads the page in firefox and chrome for me on osx...

I can confirm that

let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);

threw net::ERR_CONNECTION_RESET 200 (OK) for me on chrome 74.0.3729.131 on Mac

Changing to include the content length fixed it.

Hello,

Just wanted to also confirm that the code in listing 20-5 throws net::ERR_CONNECTION_RESET 200 (OK) unless I change the response to the include the content length.

OS: macOS Mojave (10.14.5)
Chrome: Version 76.0.3809.87 (Official Build) (64-bit)

Edit: though the 20-5 code listing does work just fine in firefox

Another anecdote, for me this works on Chrome but I get connection reset on firefox, so the opposite of some others here :thinking:

Adding the Content-Length header to the HTTP request did not fix the ERR_CONNECTION_RESET error in Chrome 79.0.3945.130 for me. However, I found out that the buffer size of 512 was too small in this case. After increasing the buffer size to 2048 and then pushing bytes to a Vec<u8> until the first null character, the number of bytes was 584. This is also easily to check by just printing the request as String and seeing partial headers like Acce (Accept-Language: en-US)

Changing the buffer size to a more conservative [0; 1024], fixed the ERR_CONNECTION_RESET error for me.

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 2048];
    stream.read(&mut buffer).unwrap();

    // Initialize an empty vector to hold bytes
    let mut request: Vec<u8> = vec![];
    for &i in buffer.iter() {
        // break on null terminator char
        if i == 0 {
            break;
        }
        request.push(i)
    }
    println!("Request size: {}", request.len()); // returns 584
// --snip--
}

Yes, @Adeleet I think you are correct, my requests had some cookies in there from another project, but using a private browser window or increasing the buffer size fixed the issue. Seems like this will be a much simpler fix! Good catch.

This was the first example I tried from the book that didn't work for me straight out of the box. Adding the Content-Length header fixed it. Why is @KludgeKML's patch not included? It's been open for 2 years now?

Why is @KludgeKML's patch not included? It's been open for 2 years now?

While this issue has been reported for a while, we (the authors) were not clear on what the cause was, and had a hard time reproducing, generally.

Now that the tree is open again, we will eventually address this, but we have a lot of work to do on the book, and not a ton of time. We'll get there.

Thanks for the book in general! It was a lot of fun going through the material and I'll keep coming back to it.

I have experienced this issue where the tutorial code fails to render the HTML using a Mac and Chrome, and found two ways to fix it (I'm a complete Rust novice, so please bear with me).

The fix recommended by @KludgeKML works, but also the part that states:

We鈥檝e made the buffer 512 bytes in size, which is big enough to hold the data of a basic request

Is incorrect, the last line and a half of the request is stripped if you do this. Increasing this buffer to 1024 also results in the page rendering successfully. My hypothesis for this is the user agent is pretty long when using a Mac and Chrome and this eats up the bytes in the request.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

devimc picture devimc  路  4Comments

mikebenfield picture mikebenfield  路  3Comments

elahn picture elahn  路  3Comments

serialhex picture serialhex  路  4Comments

ctsa picture ctsa  路  3Comments