Expand description
async fn(HttpRequest) -> Result<HttpResponse, Error>
§Overview
tower-http is a library that provides HTTP-specific middleware and utilities built on top of tower.
All middleware uses the http and http-body crates as the HTTP abstractions. That means they’re compatible with any library or framework that also uses those crates, such as hyper, tonic, and warp.
§Example server
This example shows how to apply middleware from tower-http to a Service and then run
that service using hyper and hyper-util.
use tower_http::{
compression::CompressionLayer,
trace::TraceLayer,
};
use tower::{ServiceBuilder, service_fn, BoxError};
use http::{Request, Response};
use std::net::{SocketAddr, Ipv6Addr};
use bytes::Bytes;
use http_body_util::Full;
use hyper_util::rt::{TokioIo, TokioExecutor};
use hyper_util::service::TowerToHyperService;
#[tokio::main]
async fn main() -> Result<(), BoxError> {
let addr = SocketAddr::from((Ipv6Addr::LOCALHOST, 8000));
let listener = tokio::net::TcpListener::bind(addr).await?;
println!("Listening on http://{}", addr);
loop {
let (socket, _) = listener.accept().await?;
tokio::spawn(async move {
let socket = TokioIo::new(socket);
// Build our middleware stack
let service = ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.layer(CompressionLayer::new())
.service_fn(handler);
// Wrap it for hyper
let hyper_service = TowerToHyperService::new(service);
if let Err(err) = hyper_util::server::conn::auto::Builder::new(TokioExecutor::new())
.serve_connection(socket, hyper_service)
.await
{
eprintln!("failed to serve connection: {err:#}");
}
});
}
}Keep in mind that while this example uses hyper, tower-http supports any HTTP client/server implementation that uses the http and http-body crates.
§Example client
tower-http middleware can also be applied to HTTP clients:
use tower_http::{
decompression::DecompressionLayer,
set_header::SetRequestHeaderLayer,
trace::TraceLayer,
classify::StatusInRangeAsFailures,
};
use tower::{ServiceBuilder, Service, ServiceExt};
use hyper_util::{rt::TokioExecutor, client::legacy::Client};
use http_body_util::Full;
use bytes::Bytes;
use http::{Request, HeaderValue, header::USER_AGENT};
#[tokio::main]
async fn main() {
let client = Client::builder(TokioExecutor::new()).build_http();
let mut client = ServiceBuilder::new()
// Add tracing and consider server errors and client
// errors as failures.
.layer(TraceLayer::new(
StatusInRangeAsFailures::new(400..=599).into_make_classifier()
))
// Set a `User-Agent` header on all requests.
.layer(SetRequestHeaderLayer::overriding(
USER_AGENT,
HeaderValue::from_static("tower-http demo")
))
// Decompress response bodies
.layer(DecompressionLayer::new())
// Wrap a `Client` in our middleware stack.
// This is possible because `Client` implements
// `tower::Service`.
.service(client);
// Make a request
let request = Request::builder()
.uri("http://example.com")
.body(Full::<Bytes>::default())
.unwrap();
let response = client
.ready()
.await
.unwrap()
.call(request)
.await
.unwrap();
}§Feature Flags
All middleware are disabled by default and can be enabled using cargo features.
For example, to enable the Trace middleware, add the “trace” feature flag in
your Cargo.toml:
tower-http = { version = "0.1", features = ["trace"] }You can use "full" to enable everything:
tower-http = { version = "0.1", features = ["full"] }§Getting Help
If you’re new to tower its guides might help. In the tower-http repo we also have a number
of examples showing how to put everything together. You’re also welcome to ask in
the #tower Discord channel or open an issue with your question.
Modules§
- add_
extension add-extension - Middleware that clones a value into each request’s extensions.
- auth
auth - Authorization related middleware.
- body
catch-panicordecompression-brordecompression-deflateordecompression-gzipordecompression-zstdorfsorlimit - Body types.
- catch_
panic catch-panic - Convert panics into responses.
- classify
- Tools for classifying responses as either success or failure.
- compression
compression-brorcompression-deflateorcompression-gziporcompression-zstd - Middleware that compresses response bodies.
- cors
cors - Middleware which adds headers for CORS.
- decompression
decompression-brordecompression-deflateordecompression-gzipordecompression-zstd - Middleware that decompresses request and response bodies.
- follow_
redirect follow-redirect - Middleware for following redirections.
- limit
limit - Middleware for limiting request bodies.
- map_
request_ body map-request-body - Apply a transformation to the request body.
- map_
response_ body map-response-body - Apply a transformation to the response body.
- metrics
metrics - Middlewares for adding metrics to services.
- normalize_
path normalize-path - Middleware that normalizes paths.
- on_
early_ drop on-early-drop - Middleware that detects when a response future or response body is dropped before completion.
- propagate_
header propagate-header - Propagate a header from the request to the response.
- request_
id request-id - Set and propagate request ids.
- sensitive_
headers sensitive-headers - Middlewares that mark headers as sensitive.
- services
Services that return responses without wrapping otherServices.- set_
header set-header - Middleware for setting headers on requests and responses.
- set_
status set-status - Middleware to override status codes.
- timeout
timeout - Middleware that applies a timeout to requests.
- trace
trace - Middleware that adds high level tracing to a
Service. - validate_
request validate-request - Middleware that validates requests.
Enums§
- Compression
Level compression-brorcompression-deflateorcompression-gziporcompression-zstdordecompression-brordecompression-deflateordecompression-gzipordecompression-zstd - Level of compression data should be compressed with.
- Latency
Unit - The latency unit used to report latencies by middleware.
Traits§
- Service
Builder Ext util - Extension trait that adds methods to
tower::ServiceBuilderfor adding middleware from tower-http. - Service
Ext util - Extension trait that adds methods to any
Servicefor adding middleware from tower-http.
Type Aliases§
- BoxError
- Alias for a type-erased error type.