是什么导致 Rust 的 TcpSocket::write() 变为 return "invalid input"?
What can cause Rust's TcpSocket::write() to return "invalid input"?
For a little fun 我想用 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);
}
响应是:
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.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);
}
插座returns "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
为什么插座return"invalid input"
? TCP 套接字不知道 HTTP 协议(我已经用 telnet 和 netcat 测试了我的请求:它是正确的),所以它不能抱怨 HTTP request/response.
这里的 "invalid input"
是什么意思?为什么这不起作用?
我的 Rust 版本(我在 OS X 10.10.1):
$ rustc --version
rustc 1.0.0-nightly (ea6f65c5f 2015-01-06 19:47:08 +0000)
"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));
returns:
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 还有许多其他问题,例如未转义的 &。
For a little fun 我想用 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);
}
响应是:
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.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);
}
插座returns "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
为什么插座return"invalid input"
? TCP 套接字不知道 HTTP 协议(我已经用 telnet 和 netcat 测试了我的请求:它是正确的),所以它不能抱怨 HTTP request/response.
这里的 "invalid input"
是什么意思?为什么这不起作用?
我的 Rust 版本(我在 OS X 10.10.1):
$ rustc --version
rustc 1.0.0-nightly (ea6f65c5f 2015-01-06 19:47:08 +0000)
"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));
returns:
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 还有许多其他问题,例如未转义的 &。