是什么导致Rust的TcpSocket :: write()返回"无效输入"?

Cor*_*lks 7 sockets rust

为了一点乐趣,我想在Rust中创建一个简单的HTTP请求.我把它扔在一起,效果很好:

use std::io::TcpStream;

fn main() {
    // This just does a "GET /" to www.stroustrup.com
    println!("Establishing connection...");
    let mut stream = TcpStream::connect("www.stroustrup.com:80").unwrap();

    println!("Writing HTTP request...");
    // unwrap() the result to make sure it succeeded, at least
    let _ = stream.write(b"GET / HTTP/1.1\r\n\
                           Host: www.stroustrup.com\r\n\
                           Accept: */*\r\n\
                           Connection: close\r\n\r\n").unwrap();

    println!("Reading response...");
    let response = stream.read_to_string().unwrap();

    println!("Printing response:");
    println!("{}", response);
}
Run Code Online (Sandbox Code Playgroud)

回应是:

Establishing connection...
Writing HTTP request...
Reading response...
Printing response:
HTTP/1.1 200 OK
...and the rest of the long HTTP response with all the HTML as I'd expect...
Run Code Online (Sandbox Code Playgroud)

但是,如果我将请求更改/C++.html/:

use std::io::TcpStream;

fn main() {
    // The only change is to "GET /C++.html" instead of "GET /"
    println!("Establishing connection...");
    let mut stream = TcpStream::connect("www.stroustrup.com:80").unwrap();

    println!("Writing HTTP request...");
    // unwrap() the result to make sure it succeeded, at least
    let _ = stream.write(b"GET /C++.html HTTP/1.1\r\n\
                           Host: www.stroustrup.com\r\n\
                           Accept: */*\r\n\
                           Connection: close\r\n\r\n").unwrap();

    println!("Reading response...");
    let response = stream.read_to_string().unwrap();

    println!("Printing response:");
    println!("{}", response);
}
Run Code Online (Sandbox Code Playgroud)

套接字返回"invalid input":

Establishing connection...
Writing HTTP request...
Reading response...
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: invalid input', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/libcore/result.rs:746
Run Code Online (Sandbox Code Playgroud)

套接字为什么会返回"invalid input"?TCP套接字不知道HTTP协议(我用telnet和netcat测试了我的请求:它是正确的),所以它不能抱怨HTTP请求/响应.

是什么"invalid input",甚至这里的意思?为什么这不起作用?

我的锈版(我在OS X 10.10.1上):

$ rustc --version
rustc 1.0.0-nightly (ea6f65c5f 2015-01-06 19:47:08 +0000)
Run Code Online (Sandbox Code Playgroud)

Cor*_*lks 9

"invalid input"误差不会从插座的到来.它来自String.如果read_to_string()呼叫更改为read_to_end(),则响应成功.显然,响应无效UTF-8.

更明确地,代码:

println!("Reading response...");
let response = stream.read_to_end().unwrap();

println!("Printing response:");
println!("{}", String::from_utf8(response));
Run Code Online (Sandbox Code Playgroud)

收益:

Err(invalid utf-8: invalid byte at index 14787)
Run Code Online (Sandbox Code Playgroud)

所以HTTP响应很糟糕.查看网页,错误在这里(?字符是问题):

Lang.Next'14 Keynote: What ? if anything ? have we learned from C++?
Run Code Online (Sandbox Code Playgroud)