如何使用Hyper 0.11的代理发送HTTP请求?我有以下工作代码发送没有代理的HTTP请求:
extern crate hyper;
extern crate tokio_core;
extern crate futures;
use futures::Future;
use hyper::Client;
use tokio_core::reactor::Core;
fn main() {
let mut core = Core::new().unwrap();
let client = Client::new(&core.handle());
let uri = "http://stackoverflow.com".parse().unwrap();
let work = client.get(uri).map(|res| {
res.status()
});
match core.run(work) {
Ok(status) => println!("Status: {}", status),
Err(e) => println!("Error: {:?}", e)
}
}
Run Code Online (Sandbox Code Playgroud)
这与如何通过Hyper代理到达HTTPS站点不重复?因为我问的是Hyper 0.11的新版本,它有一个完全不同的API,与以前的版本不兼容.
我正在尝试解析HTTP请求的HTML响应.我正在使用hyper来处理请求,使用html5ever进行解析.HTML将非常大,我不需要完全解析它 - 我只需要从标签中识别一些数据,所以我更愿意流式传输它.从概念上讲,我想做的事情如下:
# bash
curl url | read_dom
/* javascript */
http.get(url).pipe(parser);
parser.on("tag", /* check tag name, attributes, and act */)
Run Code Online (Sandbox Code Playgroud)
到目前为止我想出的是:
extern crate hyper;
extern crate html5ever;
use std::default::Default
use hyper::Client;
use html5ever::parse_document;
use html5ever::rcdom::{RcDom};
fn main() {
let client = Client::new();
let res = client.post(WEBPAGE)
.header(ContentType::form_url_encoded())
.body(BODY)
.send()
.unwrap();
res.read_to_end(parse_document(RcDom::default(),
Default::default().from_utf8().unwrap()));
}
Run Code Online (Sandbox Code Playgroud)
看起来read_to_end我想调用读取字节的响应的方法,但我不清楚如何将它传递给HTML文档阅读器......如果这是可能的话.
说明parse_document要使用的文档,from_utf8或者from_bytes输入是否以字节为单位(即它).
看来我需要从响应中创建一个接收器,但这就是我被困住的地方.我也不清楚如何创建事件来监听标签启动,这是我感兴趣的.
我看过这个html5ever的例子似乎做了我想做的事情并且走了DOM,但是我不能让这个例子本身运行 - 要么它已经过时了,要么卷须/ html5ever太新了.这似乎也解析了整个HTML而不是流,但我不确定.
是否有可能对我们想要对这些库的当前实现做什么?
这是如何在 Rust 中的闭包内重用外部作用域中的值的延续?,为了更好的呈现,开通了新的Q。
// main.rs
// The value will be modified eventually inside `main`
// and a http request should respond with whatever "current" value it holds.
let mut test_for_closure :Arc<RefCell<String>> = Arc::new(RefCell::from("Foo".to_string()));
// ...
// Handler for HTTP requests
// From https://docs.rs/hyper/0.14.8/hyper/service/fn.service_fn.html
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
if req.version() == Version::HTTP_11 {
let foo:String = *test_for_closure.borrow();
Ok(Response::new(Body::from(foo.as_str())))
} else {
Err("not HTTP/1.1, abort connection")
}
}))
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,我得到RefCell<std::string::String> cannot be …
我有
hyper = "0.10"
Run Code Online (Sandbox Code Playgroud)
以下代码:
let client = Client::new();
let mut res = client.get("https://google.com").send().unwrap();
Run Code Online (Sandbox Code Playgroud)
Rust给我错误消息,好像它没有SSL支持:
Http的方案无效
这是在Debian jessie的Rust 1.14.0上.
如何让Hyper将SSL连接到HTTPS URL?
我正在使用 Hyper 编写一个“hello world”HTTP 服务器,但是在尝试导入它们时我无法找到Server和模块。rt
调用时cargo run,我看到以下错误消息:
26 | let server = hyper::Server::bind(&addr).serve(router);
| ^^^^^^ could not find `Server` in `hyper`
Run Code Online (Sandbox Code Playgroud)
我肯定遗漏了一些关于 Rust 和 Hyper 的明显内容。我想做的是编写尽可能干/简单的东西,只使用 HTTP 层和一些基本路由。我想包含尽可能少的第三方依赖项,例如避免 Tokio,我认为它涉及异步行为,但我不确定上下文,因为我是 Rust 新手。
看起来我必须使用 futures,所以我包含了这个依赖项,也许 futures 只适用于async保留字(我不确定它是来自 Tokio 还是 Rust 本身)。
令我困惑的是,在 Hyper 示例中,我确实看到了像 之类的导入use hyper::{Body, Request, Response, Server};,因此该Server东西一定存在于某处。
这些是以下依赖项Cargo.toml:
hyper = "0.14.12"
serde_json = "1.0.67"
futures = "0.3.17"
Run Code Online (Sandbox Code Playgroud)
这是以下代码main.rs:
26 | let server = …Run Code Online (Sandbox Code Playgroud) 我试图通过使用Hyper 0.10实现一个简单的内存URL缩短器来学习Rust.我遇到了一个问题,我认为这是因为我试图HashMap在我的处理程序中关闭一个mutable :
fn post(mut req: Request, mut res: Response, short_uris: &mut HashMap<&str, &str>) {
let mut body = String::new();
match req.read_to_string(&mut body) {
Ok(_) => {
let key = short_uris.len();
short_uris.insert(&key.to_string(), &body.to_string());
*res.status_mut() = StatusCode::Created;
res.start().unwrap().write(&key.to_string().into_bytes());
},
Err(_) => *res.status_mut() = StatusCode::BadRequest
}
}
fn get(req: Request, mut res: Response, short_uris: &HashMap<&str, &str>) {
match req.uri.clone() {
AbsolutePath(path) => {
match short_uris.get::<str>(&path) {
Some(short_uri) => {
*res.status_mut() = StatusCode::MovedPermanently;
res.headers_mut().set(Location(short_uri.to_string()));
},
None => *res.status_mut() = StatusCode::NotFound
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个网络服务器,它接受一些 JSON 参数,并将它们转换为一个结构,然后将其存储在我的应用程序中的其他位置。
我在名为 status.rs 的文件中有这个数据结构:
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Status {
pub id: String,
pub rssi: Option<i8>,
pub carrier: Option<String>,
pub timestamp: u64,
}
Run Code Online (Sandbox Code Playgroud)
然后,我在 Hyper 的服务中使用以下代码来尝试解析请求的正文并将其转换为我的结构。唯一的区别是我想根据服务器上的时间戳添加时间戳字段,而不是客户端上的:
let timestamp: u64 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("PANIC! Time is running backwards!")
.as_secs();
Box::new(req.into_body().concat2().map(|body| {
let body_bytes = body.into_bytes();
let body_str = match str::from_utf8(&body_bytes) {
Ok(v) => v,
Err(e) => {
// TODO: this is shitty error handling
panic!("Unable to read UTF8 input: {}", e);
}
};
let …Run Code Online (Sandbox Code Playgroud) 我在将附加状态传递给我的服务函数时遇到问题,但我无法理清闭包中的生命周期。教程似乎都没有解决这个问题:
https://docs.rs/hyper/0.13.4/hyper/server/index.html
https://docs.rs/hyper/0.13.4/hyper/service/fn.make_service_fn.html
相关代码:
#[tokio::main]
async fn main() {
let addr = ([127, 0, 0, 1], 8080).into();
let db = Arc::new(Mutex::new(Slab::new()));
let server = Server::bind(&addr).serve(make_service_fn(|_conn| async {
let db = db.clone();
Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
}));
if let Err(e) = server.await {
eprintln!("server error: {}", e)
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
Compiling hyper-microservice v0.1.0 (/data/repos/rust/hyper-microservice)
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:121:66
|
121 | Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
| ^^^ …Run Code Online (Sandbox Code Playgroud) 例如,当用户访问时http://127.0.0.1:8080/hello,如果查询参数id为1,则返回纯文本响应。如果id是2,给出一个json结构。
概括:
| id(输入) | 状态码 | 内容类型 | 身体 |
|---|---|---|---|
| 1 | 200 | 应用程序/json | {“名称”:“世界”} |
| 2 | 400 | 文本/纯文本 | 没有这样的人 |
struct HelloParam {
id: u16,
}
struct HelloResponse {
name: String,
}
async fn hello_get(Query(params): Query<HelloParam>) -> Response {
// how to implement it?
}
let router= Router::new().route("/hello", get(hello_get));
Run Code Online (Sandbox Code Playgroud)