Что может вызвать TcpSocket::write() Rust для возврата "недопустимого ввода"?

скачать я хотел сделать простой HTTP-запрос в Rust. Я бросил это вместе, и это отлично работает:

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.1rn
                           Host: www.stroustrup.comrn
                           Accept: */*rn
                           Connection: closernrn").unwrap();

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

    println!("Printing response:");
    println!("{}", response);
}

ответ:

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...

однако, если я изменю запрос на /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.1rn
                           Host: www.stroustrup.comrn
                           Accept: */*rn
                           Connection: closernrn").unwrap();

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

    println!("Printing response:");
    println!("{}", response);
}

возвращает сокет "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

почему сокет возвращается "invalid input"? Сокет TCP не знает протокола HTTP (и я протестировал свой запрос с помощью telnet и netcat: это правильно), поэтому он не может жаловаться на HTTP-запрос/ответ.

что значит "invalid input" значит здесь? Почему это не работает?

моя версия rust (я на OS X 10.10.1):

$ rustc --version
rustc 1.0.0-nightly (ea6f65c5f 2015-01-06 19:47:08 +0000)

2 ответов


The "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));

возвращает:

Err(invalid utf-8: invalid byte at index 14787)

таким образом, HTTP-ответ плохой. Глядя на веб-страницу, ошибка здесь ( проблема в символах):

Lang.Next'14 Keynote: What � if anything � have we learned from C++?

оскорбительными символами являются 0x96, действительно недопустимый utf-8. Это должно быть U + 2013 – Документ либо iso-8859-1, либо windows 1252. Существует ряд других проблем с этим HTML, таких как unescaped&.