如何从Rust发出HTTP请求?我似乎无法在核心库中找到任何东西.
我不需要解析输出,只需发出请求并检查HTTP响应代码.
奖励标记,如果有人可以告诉我如何URL编码我的URL上的查询参数!
Isa*_*rey 55
在Rust中执行HTTP的最简单方法是reqwest.它是使Hyper更易于使用的包装器.
Hyper是Rust的一个流行的HTTP库,它使用两个库:Tokio的事件循环用于发出非阻塞请求,期货-rs用于期货/承诺.下面是一个基于Hyper的示例,其中很大程度上受到其文档中的示例的启发.
// Rust 1.36, Hyper 0.12.35, tokio-core 0.1.17, futures 0.1.29
extern crate futures;
extern crate hyper;
extern crate tokio_core;
use futures::{Future};
use hyper::{Client, Uri};
use tokio_core::reactor::Core;
fn main() {
// Core is the Tokio event loop used for making a non-blocking request
let mut core = Core::new().unwrap();
let client = Client::new();
let url : Uri = "http://httpbin.org/response-headers?foo=bar".parse().unwrap();
assert_eq!(url.query(), Some("foo=bar"));
let request_result = core.run(client
.get(url)
.map(|res| {
println!("Response: {}", res.status());
})
.map_err(|err| {
println!("Error: {}", err);
})
);
}
Run Code Online (Sandbox Code Playgroud)
在Cargo.toml
:
[dependencies]
hyper = "0.12.35"
tokio-core = "0.1.17"
futures = "0.1.29"
Run Code Online (Sandbox Code Playgroud)
对于后代,我在下面留下了我的原始答案,但请参见上面的Rust 1.19更新(截至本文撰写时的最新稳定版).
我相信你要找的是标准库.现在在rust-http和Chris Morgan的答案是在可预见的未来当前Rust的标准方式.我不确定我能带你走多远(希望我没有带你错误的方向!),但是你会想要这样的东西:
// Rust 0.6 -- old code
/*
extern mod std;
use std::net_ip;
use std::uv;
fn main() {
let iotask = uv::global_loop::get();
let result = net_ip::get_addr("www.duckduckgo.com", &iotask);
io::println(fmt!("%?", result));
}
*/
Run Code Online (Sandbox Code Playgroud)
至于编码,在src/libstd/net_url.rs中的单元测试中有一些例子.
Chr*_*gan 22
我一直在研究rust-http,它已成为Rust的事实上的 HTTP库(Servo使用它); 它目前还远未完整且记录很少.这是一个使用状态代码发出请求并执行操作的示例:
extern mod http;
use http::client::RequestWriter;
use http::method::Get;
use http::status;
use std::os;
fn main() {
let request = RequestWriter::new(Get, FromStr::from_str(os::args()[1]).unwrap());
let response = match request.read_response() {
Ok(response) => response,
Err(_request) => unreachable!(), // Uncaught condition will have failed first
};
if response.status == status::Ok {
println!("Oh goodie, I got me a 200 OK response!");
} else {
println!("That URL ain't returning 200 OK, it returned {} instead", response.status);
}
}
Run Code Online (Sandbox Code Playgroud)
使用URL作为唯一的命令行参数运行此代码,它将检查状态代码!(仅限HTTP;无HTTPS.)
比较src/examples/client/client.rs
一个更多的例子.
rust-http跟踪生锈的主要分支.目前它将在刚刚发布的Rust 0.8中运行,但很快就会出现重大变化. 实际上,Rust-http没有版本可以在Rust 0.8上运行 - 有一个突破性的变化,在发布之前的隐私规则中无法解决,留下了一些生锈的http依赖于extra :: url不可访问.这已经修复了,但是它留下了锈-http与Rust 0.8不兼容.
至于查询字符串编码问题,目前应该用extra::url::Query
(typedef for ~[(~str, ~str)]
)来完成.适当的转换功能:
extra::url::query_from_str
(对不起,目前不能使用它,因为它是私有的.公关即将公开.同时,这个链接实际上不应该工作,它只能用于https://github.com/ mozilla/rust/issues/7476.)
dvd*_*plm 15
使用curl绑定.坚持下去Cargo.toml
:
[dependencies.curl]
git = "https://github.com/carllerche/curl-rust"
Run Code Online (Sandbox Code Playgroud)
......这个在src/main.rs
:
extern crate curl;
use curl::http;
fn main(){
let resp = http::handle()
.post("http://localhost:3000/login", "username=dude&password=sikrit")
.exec().unwrap();
println!("code={}; headers={}; body={}",
resp.get_code(), resp.get_headers(), resp.get_body());
}
Run Code Online (Sandbox Code Playgroud)
小智 9
我更喜欢依赖项数较少的板条箱,所以我会推荐这些:
use minreq;
fn main() -> Result<(), minreq::Error> {
let o = minreq::get("https://speedtest.lax.hivelocity.net").send()?;
let s = o.as_str()?;
print!("{}", s);
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
use {http_req::error, http_req::request, std::io, std::io::Write};
fn main() -> Result<(), error::Error> {
let mut a = Vec::new();
request::get("https://speedtest.lax.hivelocity.net", &mut a)?;
io::stdout().write(&a)?;
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
为了详细说明Isaac Aggrey 的答案,这里有一个使用reqwest库发出带有查询参数的 POST 请求的示例。
Cargo.toml
[package]
name = "play_async"
version = "0.1.0"
edition = "2018"
[dependencies]
reqwest = "0.10.4"
tokio = { version = "0.2.21", features = ["macros"] }
Run Code Online (Sandbox Code Playgroud)
代码
use reqwest::Client;
type Error = Box<dyn std::error::Error>;
type Result<T, E = Error> = std::result::Result<T, E>;
async fn post_greeting() -> Result<()> {
let client = Client::new();
let req = client
// or use .post, etc.
.get("https://webhook.site/1dff66fd-07ff-4cb5-9a77-681efe863747")
.header("Accepts", "application/json")
.query(&[("hello", "1"), ("world", "ABCD")]);
let res = req.send().await?;
println!("{}", res.status());
let body = res.bytes().await?;
let v = body.to_vec();
let s = String::from_utf8_lossy(&v);
println!("response: {} ", s);
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
post_greeting().await?;
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
转到https://webhook.site并创建您的 webhook 链接并更改代码以匹配。您将看到服务器实时收到请求。
此示例最初基于Bastian Gruber 的示例,并已针对现代 Rust 语法和较新的 crate 版本进行了更新。
归档时间: |
|
查看次数: |
34462 次 |
最近记录: |