Expand description
Runtime glue, a pooling client, and server helpers for hyper.
- Crate
::hyper_util. - docs.rs
- crates.io
- GitHub
hyper 1.x is runtime-agnostic:
it reads and writes through its own I/O traits
and spawns tasks through an executor trait,
but provides no implementations of either.
hyper-util provides them for tokio,
along with the higher-level pieces that hyper 1.0
moved out of its core.
The parts used most:
TokioIo- adapts atokiosocket to hyper’s I/O traitsTokioExecutor- spawns hyper’s background tasks ontokioClient- a connection-pooling HTTP clientauto::Builder- serves a connection as HTTP/1 or HTTP/2, whichever the client speaksTowerToHyperService- runs atowerservice as a hyper service
Most applications should use reqwest as a client,
which is built on hyper-util.
Use hyper-util directly alongside hyper
when building servers or custom clients.
Message bodies come from http_body_util.
§Examples
Serving a connection with hyper and requesting it with Client:
use bytes::Bytes;
use http_body_util::{BodyExt, Full};
use hyper::{Request, Response, body::Incoming, server::conn::http1, service::service_fn};
use hyper_util::client::legacy::Client;
use hyper_util::rt::{TokioExecutor, TokioIo};
use std::convert::Infallible;
use tokio::net::TcpListener;
async fn hello(_req: Request<Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
Ok(Response::new(Full::new(Bytes::from("hello"))))
}
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
tokio::spawn(async move {
let (stream, _) = listener.accept().await.unwrap();
http1::Builder::new()
.serve_connection(TokioIo::new(stream), service_fn(hello))
.await
.unwrap();
});
let client = Client::builder(TokioExecutor::new()).build_http::<Full<Bytes>>();
let uri = format!("http://{addr}/").parse().unwrap();
let response = client.get(uri).await.unwrap();
let body = response.into_body().collect().await.unwrap().to_bytes();
assert_eq!(body, "hello");
}