gpt4 book ai didi

http - std::io::TcpStream::read_as_string 返回空字符串

转载 作者:可可西里 更新时间:2023-11-01 02:33:59 24 4
gpt4 key购买 nike

我想在 Rust 中创建一个类似 curl 的函数。

到目前为止,这是我使用的代码:

match Url::parse(url) { 
Ok(u) => {
match TcpStream::connect(u.host.as_slice(), 80) {
Ok(mut socket) => {
let req = format!(
"GET {:s} HTTP/1.1\r\nHost: {:s}\r\nAccept: */*\r\nContent-Length: 0\r\nContent-Type: aplication/x-www-form-urlencoded\r\n",
u.path.path.as_slice(), u.host
);
socket.write(req.as_bytes());
match socket.read_to_string() {
Ok(res) => println!("{}", res.as_slice()),
Err(e) => fail!("Error: {}", e)
};
drop(socket);
},
Err(e) => fail!("Error: {}", e)
};
},
Err(e) => fail!("Error: {}", e)
};

问题是,如果 HTTP 请求格式正确,

println!("{}", res.as_slice())

不会显示任何带有任何 url 的内容。

如果格式不正确,相同的代码将显示 403 或 400 错误。这是否意味着套接字变量已填充?

问题可能来自哪里?服务器还是请求?

对了,代码有点长,我想用宏试试!但是在执行时会引发错误,例如:

try!(TcpStream::connect(u.host.as_slice(), 80)

最佳答案

看起来您的请求确实不正确,但不是服务器可以告诉您的方式。

GET {:s} HTTP/1.1\r\nHost: {:s}\r\nAccept: */*\r\nContent-Length: 0\r\nContent-Type: aplication/x-www-form-urlencoded\r\n

你看,一个 HTTP 请求应该以 两个 换行结束,即两个 \r\n 序列。 GET 请求也不能有正文(尽管大多数 Web 服务器可能会忽略它):

GET {:s} HTTP/1.1\r\nHost: {:s}\r\nAccept: */*\r\n\r\n

这个请求应该有效。

至于try!,您似乎是想在main() 函数或类似的函数中使用它,对吗? try! 的目的是在出错时从函数返回,即:

try!(TcpStream::connect(u.host.as_slice(), 80))

被重写为

match TcpStream::connect(u.host.as_slice(), 80) {
Ok(s) => s,
Err(e) => return Err(e)
}

如果您的函数不返回Result,它就不会工作。所以你的代码看起来会更好:

extern crate url;

use std::io::{IoResult, File, TcpStream};

use url::Url;

fn download_file(url: &Url, file: &Path) -> IoResult<()> {
let mut socket = try!(TcpStream::connect(url.host.as_slice(), 80));
let req = format!(
"GET {:s} HTTP/1.1\r\nHost: {:s}\r\nAccept: */*\r\n\r\n",
url.path.path.as_slice(), url.host
);

try!(socket.write(req.as_bytes()));

let res = try!(socket.read_to_end());

let mut file = File::create(file);
try!(file.write(res.as_slice()));

Ok(())
}

fn main() {
let url = "http://kitten.jpg.to/";
match Url::parse(url) {
Ok(url) => match download_file(&url, &Path::new("/tmp/kitten_link.http")) {
Ok(_) => println!("Download successful"),
Err(e) => fail!("Error: {}", e)
},
Err(e) => fail!("Error: {}", e)
}
}

顺便说一句,您也不需要显式地删除套接字或其他东西。当它们超出范围时,它们会自动销毁。我还将 read_to_string() 更改为 read_to_end(),因为二进制文件在通过 String 传递后将不正确。

关于http - std::io::TcpStream::read_as_string 返回空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24689601/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com