我正在使用Rust中一个非常简单的HTTP客户端,它基于hyper(GitHub,crates.io)包.
当我尝试examples/client.rs使用cargo build(以及使用rustc src/main.rs)在新的Cargo项目中复制文件时,我会收到由导入失败导致的多个错误hyper.
这是我的最高层main.rs:
extern crate hyper;
use hyper::client::{Client, Request, Response, DefaultTransport as HttpStream};
use hyper::header::Connection;
use hyper::{Decoder, Encoder, Next};
Run Code Online (Sandbox Code Playgroud)
除了一些注释之外,文件的其余部分与存储库中的examples/client.rs文件相同hyper.
在编译时,我收到以下错误:
src/main.rs:10:48: 10:78 error: unresolved import `hyper::client::DefaultTransport`. There is no `DefaultTransport` in `hyper::client` [E0432]
src/main.rs:10 use hyper::client::{Client, Request, Response, DefaultTransport as HttpStream};
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:10:48: 10:78 help: run `rustc --explain E0432` to see a detailed explanation
src/main.rs:12:13: 12:20 error: …Run Code Online (Sandbox Code Playgroud) 如何使用异步Hyper(> = 0.11)设置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) 我学习了Rust,我尝试构建一个基于hyper的微路由系统(它仅用于学习目的,我知道框架存在).
我不知道如何与一个"复杂"类型共享hyper::server::Handler.我读了错误信息,但不幸的是,我不明白如何解决它(大多数时候,生锈编译器只是说要解决什么,现在我不确定理解).
这是我尝试过的(非)工作过度简化示例:
extern crate hyper;
use std::sync::Mutex;
use hyper::*;
type Route = (method::Method, String, Box<Fn(server::Request, server::Response)>);
struct MyHandler {
routes: Mutex<Vec<Route>>
}
impl server::Handler for MyHandler {
fn handle(&self, req: server::Request, mut res: server::Response) {
// This is not important
}
}
fn main() {
// This is not important
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error: the trait bound `for<'r, 'r, 'r> std::ops::Fn(hyper::server::Request<'r, 'r>, hyper::server::Response<'r>) + 'static: std::marker::Send` is not satisfied [--explain E0277]
--> src/main.rs:12:10
|>
12 |> impl server::Handler …Run Code Online (Sandbox Code Playgroud) 我想使用Hyper的当前主分支编写服务器,该分支保存由POST请求传递的消息,并将此消息发送到每个传入的GET请求.
我有这个,大多是从Hyper示例目录中复制的:
extern crate futures;
extern crate hyper;
extern crate pretty_env_logger;
use futures::future::FutureResult;
use hyper::{Get, Post, StatusCode};
use hyper::header::{ContentLength};
use hyper::server::{Http, Service, Request, Response};
use futures::Stream;
struct Echo {
data: Vec<u8>,
}
impl Echo {
fn new() -> Self {
Echo {
data: "text".into(),
}
}
}
impl Service for Echo {
type Request = Request;
type Response = Response;
type Error = hyper::Error;
type Future = FutureResult<Response, hyper::Error>;
fn call(&self, req: Self::Request) -> Self::Future {
let resp = match …Run Code Online (Sandbox Code Playgroud) 我想从我的超级服务器提供一些静态文件(.js,.css等)。
目前,我能想到的唯一方法是将文件内联为字符串/在启动时加载它们。
是否有更好的方法直接提供整个目录或所选文件?
我正在尝试调整Hyper basic 客户端示例以同时获取多个 URL。
这是我目前拥有的代码:
extern crate futures;
extern crate hyper;
extern crate tokio_core;
use std::io::{self, Write};
use std::iter;
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;
fn get_url() {
let mut core = Core::new().unwrap();
let client = Client::new(&core.handle());
let uris: Vec<_> = iter::repeat("http://httpbin.org/ip".parse().unwrap()).take(50).collect();
for uri in uris {
let work = client.get(uri).and_then(|res| {
println!("Response: {}", res.status());
res.body().for_each(|chunk| {
io::stdout()
.write_all(&chunk)
.map_err(From::from)
})
});
core.run(work).unwrap();
}
}
fn main() {
get_url();
}
Run Code Online (Sandbox Code Playgroud)
它似乎没有同时进行(需要很长时间才能完成),我是否以错误的方式将工作交给了核心?
我想使用 hyper 创建一个小型 Rust HTTP 代理,它接受请求、转发请求并转储请求 + 正文。
基于这个例子,代理部分工作正常。
但是,我不能简单地复制和打印请求正文。我的主要问题是请求正文不能简单地复制到Vec<u8>. 我无法deconstruct请求读取正文然后稍后创建它,因为无法将解构的标头添加到新请求中。
以下代码显示了我的最小 HTTP 代理示例:
extern crate futures;
extern crate hyper;
extern crate tokio_core;
use futures::{Future, Stream};
use hyper::{Body, Client, StatusCode};
use hyper::client::HttpConnector;
use hyper::header::{ContentLength, ContentType};
use hyper::server::{Http, Request, Response, Service};
use tokio_core::reactor::Core;
type HTTPClient = Client<HttpConnector, Body>;
struct Server {
client: HTTPClient,
}
impl Server {
pub fn new(client: HTTPClient) -> Server {
Server { client: client }
}
}
impl Service for Server …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Hyper Web 服务器中创建一个计数器来计算它收到的请求数。我正在使用 aArc<Mutex<u64>>来保持计数。但是,我一直无法弄清楚闭包的正确组合move和.clone()满足闭包的类型。这是一些编译代码,但在每个请求上重置计数器:
extern crate hyper;
use hyper::rt::Future;
use hyper::service::service_fn_ok;
use hyper::{Body, Response, Server};
use std::sync::{Arc, Mutex};
fn main() {
let addr = "0.0.0.0:3000".parse().unwrap();
// FIXME want to create the counter here, not below
let server = Server::bind(&addr)
.serve(|| {
service_fn_ok(|_req| {
let counter = Arc::new(Mutex::new(0));
use_counter(counter)
})
})
.map_err(|e| eprintln!("Error: {}", e));
hyper::rt::run(server)
}
fn use_counter(counter: Arc<Mutex<u64>>) -> Response<Body> {
let mut data = counter.lock().unwrap();
*data += 1;
Response::new(Body::from(format!("Counter: {}\n", data))) …Run Code Online (Sandbox Code Playgroud) 我有一个无法在编译时计算的值。它需要在任何应用程序代码运行之前进行计算,然后它只会在应用程序的整个生命周期中被读取。它还需要传递给执行者,例如处理程序tokio和hyper处理程序。
我怎样才能安全、惯用地创造这样的价值,并且不会造成不必要的性能损失?
main并将其传递给hyper,它的寿命就不够长。lazy_static!,则仅在首次访问时才计算它。如果无法计算,那么我也不想运行应用程序的其余部分。我宁愿知道在启动应用程序时无法连接到数据库,而不是在客户端发出请求时无法连接到数据库。static mut,那么我就无法在安全代码中使用它。理想情况下,我想做类似的事情:
#[tokio::main]
pub async fn main() {
let db = init_db();
// This uses a hyper server, passes db around
// to tokio and hyper handlers, etc.
run_app(&db);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试向每个跟踪事件添加请求 ID。tower_http::trace我可以这样做:
#[derive(Clone)]
pub struct RequestSpan;
impl<B> tower_http::trace::MakeSpan<B> for RequestSpan {
fn make_span(&mut self, request: &http::Request<B>) -> tracing::Span {
tracing::error_span!(
"rq",
id = %ulid::Ulid::new().to_string(),
method = %request.method(),
uri = %request.uri(),
version = ?request.version(),
)
}
}
...
let middleware_stack = tower::ServiceBuilder::new()
.layer(TraceLayer::new_for_http().make_span_with(RequestSpan))
Run Code Online (Sandbox Code Playgroud)
它在服务器范围内工作,但我还需要将请求 ID 传递到外部任务队列中。有什么建议么?
hyper ×10
rust ×10
rust-tokio ×5
asynchronous ×1
http ×1
rust-axum ×1
rust-tower ×1
server ×1
timeout ×1