# Tower Http > [Source](../../src/tower_http/add_extension.rs.html#1-167) --- # Source: https://docs.rs/tower-http/latest/tower_http/add_extension/ [tower_http](../index.html) # Module add_extension Copy item path [Source](../../src/tower_http/add_extension.rs.html#1-167) Available on **crate feature add-extension** only. Expand description Middleware that clones a value into each request’s extensions. ## §Example ``` use tower_http::add_extension::AddExtensionLayer; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use http::{Request, Response}; use bytes::Bytes; use http_body_util::Full; use std::{sync::Arc, convert::Infallible}; // Shared state across all request handlers --- in this case, a pool of database connections. struct State { pool: DatabaseConnectionPool, } async fn handle(req: Request>) -> Result>, Infallible> { // Grab the state from the request extensions. let state = req.extensions().get::>().unwrap(); Ok(Response::new(Full::default())) } // Construct the shared state. let state = State { pool: DatabaseConnectionPool::new(), }; let mut service = ServiceBuilder::new() // Share an `Arc` with all requests. .layer(AddExtensionLayer::new(Arc::new(state))) .service_fn(handle); // Call the service. let response = service .ready() .await? .call(Request::new(Full::default())) .await?; ``` ## Structs§ [AddExtension](struct.AddExtension.html) Middleware for adding some shareable value to [request extensions](https://docs.rs/http/latest/http/struct.Extensions.html) . [AddExtensionLayer](struct.AddExtensionLayer.html) [Layer](https://docs.rs/tower-layer/0.3.3/x86_64-unknown-linux-gnu/tower_layer/trait.Layer.html) for adding some shareable value to [request extensions](https://docs.rs/http/latest/http/struct.Extensions.html) . --- # Source: https://docs.rs/tower-http/latest/tower_http/auth/ [tower_http](../index.html) # Module auth Copy item path [Source](../../src/tower_http/auth/mod.rs.html#1-13) Available on **crate feature auth** only. Expand description Authorization related middleware. ## Modules§ [add_authorization](add_authorization/index.html) Add authorization to requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header. [async_require_authorization](async_require_authorization/index.html) Authorize requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header asynchronously. [require_authorization](require_authorization/index.html) Deprecated Authorize requests using [ValidateRequest](../validate_request/trait.ValidateRequest.html) . ## Structs§ [AddAuthorization](struct.AddAuthorization.html) Middleware that adds authorization all requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header. [AddAuthorizationLayer](struct.AddAuthorizationLayer.html) Layer that applies [AddAuthorization](struct.AddAuthorization.html) which adds authorization to all requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header. [AsyncRequireAuthorization](struct.AsyncRequireAuthorization.html) Middleware that authorizes all requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header. [AsyncRequireAuthorizationLayer](struct.AsyncRequireAuthorizationLayer.html) Layer that applies [AsyncRequireAuthorization](struct.AsyncRequireAuthorization.html) which authorizes all requests using the [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header. ## Traits§ [AsyncAuthorizeRequest](trait.AsyncAuthorizeRequest.html) Trait for authorizing requests. --- # Source: https://docs.rs/tower-http/latest/tower_http/body/ [tower_http](../index.html) # Module body Copy item path [Source](../../src/tower_http/body.rs.html#1-121) Available on **crate features catch-panic or decompression-br or decompression-deflate or decompression-gzip or decompression-zstd or fs or limit** only. Expand description Body types. All these are wrappers around other body types. You shouldn’t have to use them in your code. Use http-body-util instead. They exist because we don’t want to expose types from http-body-util in tower-https public API. ## Structs§ [Full](struct.Full.html) [Limited](struct.Limited.html) [UnsyncBoxBody](struct.UnsyncBoxBody.html) --- # Source: https://docs.rs/tower-http/latest/tower_http/catch_panic/ [tower_http](../index.html) # Module catch_panic Copy item path [Source](../../src/tower_http/catch_panic.rs.html#1-409) Available on **crate feature catch-panic** only. Expand description Convert panics into responses. Note that using panics for error handling is not recommended. Prefer instead to use Result whenever possible. ## §Example ``` use http::{Request, Response, header::HeaderName}; use std::convert::Infallible; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use tower_http::catch_panic::CatchPanicLayer; use http_body_util::Full; use bytes::Bytes; async fn handle(req: Request>) -> Result>, Infallible> { panic!("something went wrong...") } let mut svc = ServiceBuilder::new() // Catch panics and convert them into responses. .layer(CatchPanicLayer::new()) .service_fn(handle); // Call the service. let request = Request::new(Full::default()); let response = svc.ready().await?.call(request).await?; assert_eq!(response.status(), 500); ``` Using a custom panic handler: ``` use http::{Request, StatusCode, Response, header::{self, HeaderName}}; use std::{any::Any, convert::Infallible}; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use tower_http::catch_panic::CatchPanicLayer; use bytes::Bytes; use http_body_util::Full; async fn handle(req: Request>) -> Result>, Infallible> { panic!("something went wrong...") } fn handle_panic(err: Box) -> Response> { let details = if let Some(s) = err.downcast_ref::() { s.clone() } else if let Some(s) = err.downcast_ref::<&str>() { s.to_string() } else { "Unknown panic message".to_string() }; let body = serde_json::json!({ "error": { "kind": "panic", "details": details, } }); let body = serde_json::to_string(&body).unwrap(); Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .header(header::CONTENT_TYPE, "application/json") .body(Full::from(body)) .unwrap() } let svc = ServiceBuilder::new() // Use `handle_panic` to create the response. .layer(CatchPanicLayer::custom(handle_panic)) .service_fn(handle); ``` ## Structs§ [CatchPanic](struct.CatchPanic.html) Middleware that catches panics and converts them into `500 Internal Server` responses. [CatchPanicLayer](struct.CatchPanicLayer.html) Layer that applies the [CatchPanic](struct.CatchPanic.html) middleware that catches panics and converts them into `500 Internal Server` responses. [DefaultResponseForPanic](struct.DefaultResponseForPanic.html) The default `ResponseForPanic` used by `CatchPanic` . [ResponseFuture](struct.ResponseFuture.html) Response future for [CatchPanic](struct.CatchPanic.html) . ## Traits§ [ResponseForPanic](trait.ResponseForPanic.html) Trait for creating responses from panics. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/compression/ # Path: compression/ [tower_http](../index.html) # Module compression Copy item path [Source](../../src/tower_http/compression/mod.rs.html#1-511) Available on **crate features`compression-br` or `compression-deflate` or `compression-gzip` or `compression-zstd`** only. Expand description Middleware that compresses response bodies. ## §Example Example showing how to respond with the compressed contents of a file. use bytes::{Bytes, BytesMut}; use http::{Request, Response, header::ACCEPT_ENCODING}; use http_body_util::{Full, BodyExt, StreamBody, combinators::UnsyncBoxBody}; use http_body::Frame; use std::convert::Infallible; use tokio::fs::{self, File}; use tokio_util::io::ReaderStream; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use tower_http::{compression::CompressionLayer, BoxError}; use futures_util::TryStreamExt; type BoxBody = UnsyncBoxBody; async fn handle(req: Request>) -> Result, Infallible> { // Open the file. let file = File::open("Cargo.toml").await.expect("file missing"); // Convert the file into a `Stream` of `Bytes`. let stream = ReaderStream::new(file); // Convert the stream into a stream of data `Frame`s. let stream = stream.map_ok(Frame::data); // Convert the `Stream` into a `Body`. let body = StreamBody::new(stream); // Erase the type because its very hard to name in the function signature. let body = body.boxed_unsync(); // Create response. Ok(Response::new(body)) } let mut service = ServiceBuilder::new() // Compress responses based on the `Accept-Encoding` header. .layer(CompressionLayer::new()) .service_fn(handle); // Call the service. let request = Request::builder() .header(ACCEPT_ENCODING, "gzip") .body(Full::::default())?; let response = service .ready() .await? .call(request) .await?; assert_eq!(response.headers()["content-encoding"], "gzip"); // Read the body let bytes = response .into_body() .collect() .await? .to_bytes(); // The compressed body should be smaller 🤞 let uncompressed_len = fs::read_to_string("Cargo.toml").await?.len(); assert!(bytes.len() < uncompressed_len); ## Modules§ [predicate](predicate/index.html "mod tower_http::compression::predicate") Predicates for disabling compression of responses. ## Structs§ [Compression](struct.Compression.html "struct tower_http::compression::Compression") Compress response bodies of the underlying service. [CompressionBody](struct.CompressionBody.html "struct tower_http::compression::CompressionBody") Response body of [`Compression`](struct.Compression.html "struct tower_http::compression::Compression"). [CompressionLayer](struct.CompressionLayer.html "struct tower_http::compression::CompressionLayer") Compress response bodies of the underlying service. [DefaultPredicate](struct.DefaultPredicate.html "struct tower_http::compression::DefaultPredicate") The default predicate used by [`Compression`](struct.Compression.html "struct tower_http::compression::Compression") and [`CompressionLayer`](struct.CompressionLayer.html "struct tower_http::compression::CompressionLayer"). [ResponseFuture](struct.ResponseFuture.html "struct tower_http::compression::ResponseFuture") Response future of [`Compression`](struct.Compression.html "struct tower_http::compression::Compression"). ## Enums§ [CompressionLevel](enum.CompressionLevel.html "enum tower_http::compression::CompressionLevel") Level of compression data should be compressed with. ## Traits§ [Predicate](trait.Predicate.html "trait tower_http::compression::Predicate") Predicate used to determine if a response should be compressed or not. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/cors/ # Path: cors/ [tower_http](../index.html) # Module cors Copy item path [Source](../../src/tower_http/cors/mod.rs.html#1-820) Available on **crate feature`cors`** only. Expand description Middleware which adds headers for [CORS](https://developer.mozilla.org/en- US/docs/Web/HTTP/CORS). ## §Example use http::{Request, Response, Method, header}; use http_body_util::Full; use bytes::Bytes; use tower::{ServiceBuilder, ServiceExt, Service}; use tower_http::cors::{Any, CorsLayer}; use std::convert::Infallible; async fn handle(request: Request>) -> Result>, Infallible> { Ok(Response::new(Full::default())) } let cors = CorsLayer::new() // allow `GET` and `POST` when accessing the resource .allow_methods([Method::GET, Method::POST]) // allow requests from any origin .allow_origin(Any); let mut service = ServiceBuilder::new() .layer(cors) .service_fn(handle); let request = Request::builder() .header(header::ORIGIN, "https://example.com") .body(Full::default()) .unwrap(); let response = service .ready() .await? .call(request) .await?; assert_eq!( response.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap(), "*", ); ## Structs§ [AllowCredentials](struct.AllowCredentials.html "struct tower_http::cors::AllowCredentials") Holds configuration for how to set the [`Access-Control-Allow-Credentials`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) header. [AllowHeaders](struct.AllowHeaders.html "struct tower_http::cors::AllowHeaders") Holds configuration for how to set the [`Access-Control-Allow-Headers`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers) header. [AllowMethods](struct.AllowMethods.html "struct tower_http::cors::AllowMethods") Holds configuration for how to set the [`Access-Control-Allow-Methods`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods) header. [AllowOrigin](struct.AllowOrigin.html "struct tower_http::cors::AllowOrigin") Holds configuration for how to set the [`Access-Control-Allow-Origin`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) header. [AllowPrivateNetwork](struct.AllowPrivateNetwork.html "struct tower_http::cors::AllowPrivateNetwork") Holds configuration for how to set the [`Access-Control-Allow-Private-Network`](https://wicg.github.io/private-network-access/) header. [Any](struct.Any.html "struct tower_http::cors::Any") Represents a wildcard value (`*`) used with some CORS headers such as [`CorsLayer::allow_methods`](struct.CorsLayer.html#method.allow_methods "method tower_http::cors::CorsLayer::allow_methods"). [Cors](struct.Cors.html "struct tower_http::cors::Cors") Middleware which adds headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). [CorsLayer](struct.CorsLayer.html "struct tower_http::cors::CorsLayer") Layer that applies the [`Cors`](struct.Cors.html "struct tower_http::cors::Cors") middleware which adds headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). [ExposeHeaders](struct.ExposeHeaders.html "struct tower_http::cors::ExposeHeaders") Holds configuration for how to set the [`Access-Control-Expose-Headers`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers) header. [MaxAge](struct.MaxAge.html "struct tower_http::cors::MaxAge") Holds configuration for how to set the [`Access-Control-Max-Age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age) header. [ResponseFuture](struct.ResponseFuture.html "struct tower_http::cors::ResponseFuture") Response future for [`Cors`](struct.Cors.html "struct tower_http::cors::Cors"). [Vary](struct.Vary.html "struct tower_http::cors::Vary") Holds configuration for how to set the [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) header. ## Functions§ [any](fn.any.html "fn tower_http::cors::any")Deprecated Represents a wildcard value (`*`) used with some CORS headers such as [`CorsLayer::allow_methods`](struct.CorsLayer.html#method.allow_methods "method tower_http::cors::CorsLayer::allow_methods"). [preflight_request_headers](fn.preflight_request_headers.html "fn tower_http::cors::preflight_request_headers") Returns an iterator over the three request headers that may be involved in a CORS preflight request. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/decompression/ # Path: decompression/ [tower_http](../index.html) # Module decompression Copy item path [Source](../../src/tower_http/decompression/mod.rs.html#1-255) Available on **crate features`decompression-br` or `decompression-deflate` or `decompression-gzip` or `decompression-zstd`** only. Expand description Middleware that decompresses request and response bodies. ## §Examples ##### §Request use bytes::Bytes; use flate2::{write::GzEncoder, Compression}; use http::{header, HeaderValue, Request, Response}; use http_body_util::{Full, BodyExt}; use std::{error::Error, io::Write}; use tower::{Service, ServiceBuilder, service_fn, ServiceExt}; use tower_http::{BoxError, decompression::{DecompressionBody, RequestDecompressionLayer}}; // A request encoded with gzip coming from some HTTP client. let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); encoder.write_all(b"Hello?")?; let request = Request::builder() .header(header::CONTENT_ENCODING, "gzip") .body(Full::from(encoder.finish()?))?; // Our HTTP server let mut server = ServiceBuilder::new() // Automatically decompress request bodies. .layer(RequestDecompressionLayer::new()) .service(service_fn(handler)); // Send the request, with the gzip encoded body, to our server. let _response = server.ready().await?.call(request).await?; // Handler receives request whose body is decoded when read async fn handler( mut req: Request>>, ) -> Result>, BoxError>{ let data = req.into_body().collect().await?.to_bytes(); assert_eq!(&data[..], b"Hello?"); Ok(Response::new(Full::from("Hello, World!"))) } ##### §Response use bytes::Bytes; use http::{Request, Response}; use http_body_util::{Full, BodyExt}; use std::convert::Infallible; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use tower_http::{compression::Compression, decompression::DecompressionLayer, BoxError}; // Some opaque service that applies compression. let service = Compression::new(service_fn(handle)); // Our HTTP client. let mut client = ServiceBuilder::new() // Automatically decompress response bodies. .layer(DecompressionLayer::new()) .service(service); // Call the service. // // `DecompressionLayer` takes care of setting `Accept-Encoding`. let request = Request::new(Full::::default()); let response = client .ready() .await? .call(request) .await?; // Read the body let body = response.into_body(); let bytes = body.collect().await?.to_bytes().to_vec(); let body = String::from_utf8(bytes).map_err(Into::::into)?; assert_eq!(body, "Hello, World!"); ## Structs§ [Decompression](struct.Decompression.html "struct tower_http::decompression::Decompression") Decompresses response bodies of the underlying service. [DecompressionBody](struct.DecompressionBody.html "struct tower_http::decompression::DecompressionBody") Response body of [`RequestDecompression`](struct.RequestDecompression.html "struct tower_http::decompression::RequestDecompression") and [`Decompression`](struct.Decompression.html "struct tower_http::decompression::Decompression"). [DecompressionLayer](struct.DecompressionLayer.html "struct tower_http::decompression::DecompressionLayer") Decompresses response bodies of the underlying service. [RequestDecompression](struct.RequestDecompression.html "struct tower_http::decompression::RequestDecompression") Decompresses request bodies and calls its underlying service. [RequestDecompressionFuture](struct.RequestDecompressionFuture.html "struct tower_http::decompression::RequestDecompressionFuture") Response future of [`RequestDecompression`] [RequestDecompressionLayer](struct.RequestDecompressionLayer.html "struct tower_http::decompression::RequestDecompressionLayer") Decompresses request bodies and calls its underlying service. [ResponseFuture](struct.ResponseFuture.html "struct tower_http::decompression::ResponseFuture") Response future of [`Decompression`](struct.Decompression.html "struct tower_http::decompression::Decompression"). --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/ # Path: follow_redirect/ [tower_http](../index.html) # Module follow_redirect Copy item path [Source](../../src/tower_http/follow_redirect/mod.rs.html#1-476) Available on **crate feature`follow-redirect`** only. Expand description Middleware for following redirections. ## §Overview The [`FollowRedirect`](struct.FollowRedirect.html "struct tower_http::follow_redirect::FollowRedirect") middleware retries requests with the inner [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown- linux-gnu/tower_service/trait.Service.html "trait tower_service::Service") to follow HTTP redirections. The middleware tries to clone the original [`Request`](https://docs.rs/http/1.1.0/x86_64-unknown-linux- gnu/http/request/struct.Request.html "struct http::request::Request") when making a redirected request. However, since [`Extensions`](https://docs.rs/http/1.1.0/x86_64-unknown-linux- gnu/http/extensions/struct.Extensions.html "struct http::extensions::Extensions") are `!Clone`, any extensions set by outer middleware will be discarded. Also, the request body cannot always be cloned. When the original body is known to be empty by [`Body::size_hint`](https://docs.rs/http-body/1.0.1/x86_64-unknown-linux- gnu/http_body/trait.Body.html#method.size_hint "method http_body::Body::size_hint"), the middleware uses `Default` implementation of the body type to create a new request body. If you know that the body can be cloned in some way, you can tell the middleware to clone it by configuring a [`policy`](policy/index.html "mod tower_http::follow_redirect::policy"). ## §Examples ### §Basic usage use http::{Request, Response}; use bytes::Bytes; use http_body_util::Full; use tower::{Service, ServiceBuilder, ServiceExt}; use tower_http::follow_redirect::{FollowRedirectLayer, RequestUri}; let mut client = ServiceBuilder::new() .layer(FollowRedirectLayer::new()) .service(http_client); let request = Request::builder() .uri("https://rust-lang.org/") .body(Full::::default()) .unwrap(); let response = client.ready().await?.call(request).await?; // Get the final request URI. assert_eq!(response.extensions().get::().unwrap().0, "https://www.rust-lang.org/"); ### §Customizing the `Policy` You can use a [`Policy`](policy/trait.Policy.html "trait tower_http::follow_redirect::policy::Policy") value to customize how the middleware handles redirections. use http::{Request, Response}; use http_body_util::Full; use bytes::Bytes; use tower::{Service, ServiceBuilder, ServiceExt}; use tower_http::follow_redirect::{ policy::{self, PolicyExt}, FollowRedirectLayer, }; #[derive(Debug)] enum MyError { TooManyRedirects, Other(tower::BoxError), } let policy = policy::Limited::new(10) // Set the maximum number of redirections to 10. // Return an error when the limit was reached. .or::<_, (), _>(policy::redirect_fn(|_| Err(MyError::TooManyRedirects))) // Do not follow cross-origin redirections, and return the redirection responses as-is. .and::<_, (), _>(policy::SameOrigin::new()); let mut client = ServiceBuilder::new() .layer(FollowRedirectLayer::with_policy(policy)) .map_err(MyError::Other) .service(http_client); // ... ## Modules§ [policy](policy/index.html "mod tower_http::follow_redirect::policy") Tools for customizing the behavior of a [`FollowRedirect`](struct.FollowRedirect.html "struct tower_http::follow_redirect::FollowRedirect") middleware. ## Structs§ [FollowRedirect](struct.FollowRedirect.html "struct tower_http::follow_redirect::FollowRedirect") Middleware that retries requests with a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service") to follow redirection responses. [FollowRedirectLayer](struct.FollowRedirectLayer.html "struct tower_http::follow_redirect::FollowRedirectLayer") [`Layer`](https://docs.rs/tower-layer/0.3.3/x86_64-unknown-linux-gnu/tower_layer/trait.Layer.html "trait tower_layer::Layer") for retrying requests with a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service") to follow redirection responses. [RequestUri](struct.RequestUri.html "struct tower_http::follow_redirect::RequestUri") Response [`Extensions`](https://docs.rs/http/1.1.0/x86_64-unknown-linux-gnu/http/extensions/struct.Extensions.html "struct http::extensions::Extensions") value that represents the effective request URI of a response returned by a [`FollowRedirect`](struct.FollowRedirect.html "struct tower_http::follow_redirect::FollowRedirect") middleware. [ResponseFuture](struct.ResponseFuture.html "struct tower_http::follow_redirect::ResponseFuture") Response future for [`FollowRedirect`](struct.FollowRedirect.html "struct tower_http::follow_redirect::FollowRedirect"). --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/ # Path: index # Crate tower_http Copy item path [Source](../src/tower_http/lib.rs.html#1-373) Expand description `async fn(HttpRequest) -> Result` ## §Overview tower-http is a library that provides HTTP-specific middleware and utilities built on top of [tower](https://crates.io/crates/tower). All middleware uses the [http](https://crates.io/crates/http) and [http- body](https://crates.io/crates/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](https://crates.io/crates/hyper), [tonic](https://crates.io/crates/tonic), and [warp](https://crates.io/crates/warp). ## §Example server This example shows how to apply middleware from tower-http to a [`Service`](https://docs.rs/tower/latest/tower/trait.Service.html) and then run that service using [hyper](https://crates.io/crates/hyper). use tower_http::{ add_extension::AddExtensionLayer, compression::CompressionLayer, propagate_header::PropagateHeaderLayer, sensitive_headers::SetSensitiveRequestHeadersLayer, set_header::SetResponseHeaderLayer, trace::TraceLayer, validate_request::ValidateRequestHeaderLayer, }; use tower::{ServiceBuilder, service_fn, BoxError}; use http::{Request, Response, header::{HeaderName, CONTENT_TYPE, AUTHORIZATION}}; use std::{sync::Arc, net::SocketAddr, convert::Infallible, iter::once}; use bytes::Bytes; use http_body_util::Full; // Our request handler. This is where we would implement the application logic // for responding to HTTP requests... async fn handler(request: Request>) -> Result>, BoxError> { // ... } // Shared state across all request handlers --- in this case, a pool of database connections. struct State { pool: DatabaseConnectionPool, } #[tokio::main] async fn main() { // Construct the shared state. let state = State { pool: DatabaseConnectionPool::new(), }; // Use tower's `ServiceBuilder` API to build a stack of tower middleware // wrapping our request handler. let service = ServiceBuilder::new() // Mark the `Authorization` request header as sensitive so it doesn't show in logs .layer(SetSensitiveRequestHeadersLayer::new(once(AUTHORIZATION))) // High level logging of requests and responses .layer(TraceLayer::new_for_http()) // Share an `Arc` with all requests .layer(AddExtensionLayer::new(Arc::new(state))) // Compress responses .layer(CompressionLayer::new()) // Propagate `X-Request-Id`s from requests to responses .layer(PropagateHeaderLayer::new(HeaderName::from_static("x-request-id"))) // If the response has a known size set the `Content-Length` header .layer(SetResponseHeaderLayer::overriding(CONTENT_TYPE, content_length_from_response)) // Authorize requests using a token .layer(ValidateRequestHeaderLayer::bearer("passwordlol")) // Accept only application/json, application/* and */* in a request's ACCEPT header .layer(ValidateRequestHeaderLayer::accept("application/json")) // Wrap a `Service` in our middleware stack .service_fn(handler); } Keep in mind that while this example uses [hyper](https://crates.io/crates/hyper), tower-http supports any HTTP client/server implementation that uses the [http](https://crates.io/crates/http) and [http- body](https://crates.io/crates/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::::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](https://doc.rust-lang.org/cargo/reference/features.html). For example, to enable the [`Trace`](trace/struct.Trace.html "struct tower_http::trace::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](https://github.com/tower- rs/tower/tree/master/guides) might help. In the tower-http repo we also have a [number of examples](https://github.com/tower-rs/tower- http/tree/master/examples) showing how to put everything together. You’re also welcome to ask in the [`#tower` Discord channel](https://discord.gg/tokio) or open an [issue](https://github.com/tower-rs/tower-http/issues/new) with your question. ## Modules§ [add_extension](add_extension/index.html "mod tower_http::add_extension")`add- extension` Middleware that clones a value into each request’s [extensions](https://docs.rs/http/latest/http/struct.Extensions.html). [auth](auth/index.html "mod tower_http::auth")`auth` Authorization related middleware. [body](body/index.html "mod tower_http::body")`catch-panic` or `decompression- br` or `decompression-deflate` or `decompression-gzip` or `decompression-zstd` or `fs` or `limit` Body types. [catch_panic](catch_panic/index.html "mod tower_http::catch_panic")`catch- panic` Convert panics into responses. [classify](classify/index.html "mod tower_http::classify") Tools for classifying responses as either success or failure. [compression](compression/index.html "mod tower_http::compression")`compression-br` or `compression-deflate` or `compression-gzip` or `compression-zstd` Middleware that compresses response bodies. [cors](cors/index.html "mod tower_http::cors")`cors` Middleware which adds headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). [decompression](decompression/index.html "mod tower_http::decompression")`decompression-br` or `decompression-deflate` or `decompression-gzip` or `decompression-zstd` Middleware that decompresses request and response bodies. [follow_redirect](follow_redirect/index.html "mod tower_http::follow_redirect")`follow-redirect` Middleware for following redirections. [limit](limit/index.html "mod tower_http::limit")`limit` Middleware for limiting request bodies. [map_request_body](map_request_body/index.html "mod tower_http::map_request_body")`map-request-body` Apply a transformation to the request body. [map_response_body](map_response_body/index.html "mod tower_http::map_response_body")`map-response-body` Apply a transformation to the response body. [metrics](metrics/index.html "mod tower_http::metrics")`metrics` Middlewares for adding metrics to services. [normalize_path](normalize_path/index.html "mod tower_http::normalize_path")`normalize-path` Middleware that normalizes paths. [propagate_header](propagate_header/index.html "mod tower_http::propagate_header")`propagate-header` Propagate a header from the request to the response. [request_id](request_id/index.html "mod tower_http::request_id")`request-id` Set and propagate request ids. [sensitive_headers](sensitive_headers/index.html "mod tower_http::sensitive_headers")`sensitive-headers` Middlewares that mark headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). [services](services/index.html "mod tower_http::services") [`Service`](https://docs.rs/tower/latest/tower/trait.Service.html)s that return responses without wrapping other [`Service`](https://docs.rs/tower/latest/tower/trait.Service.html)s. [set_header](set_header/index.html "mod tower_http::set_header")`set-header` Middleware for setting headers on requests and responses. [set_status](set_status/index.html "mod tower_http::set_status")`set-status` Middleware to override status codes. [timeout](timeout/index.html "mod tower_http::timeout")`timeout` Middleware that applies a timeout to requests. [trace](trace/index.html "mod tower_http::trace")`trace` Middleware that adds high level [tracing](https://crates.io/crates/tracing) to a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service"). [validate_request](validate_request/index.html "mod tower_http::validate_request")`validate-request` Middleware that validates requests. ## Enums§ [CompressionLevel](enum.CompressionLevel.html "enum tower_http::CompressionLevel")`compression-br` or `compression-deflate` or `compression-gzip` or `compression-zstd` or `decompression-br` or `decompression-deflate` or `decompression-gzip` or `decompression-zstd` Level of compression data should be compressed with. [LatencyUnit](enum.LatencyUnit.html "enum tower_http::LatencyUnit") The latency unit used to report latencies by middleware. ## Traits§ [ServiceBuilderExt](trait.ServiceBuilderExt.html "trait tower_http::ServiceBuilderExt")`util` Extension trait that adds methods to [`tower::ServiceBuilder`](https://docs.rs/tower/0.5.2/x86_64-unknown-linux-gnu/tower/builder/struct.ServiceBuilder.html "struct tower::builder::ServiceBuilder") for adding middleware from tower-http. [ServiceExt](trait.ServiceExt.html "trait tower_http::ServiceExt")`util` Extension trait that adds methods to any [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service") for adding middleware from tower-http. ## Type Aliases§ [BoxError](type.BoxError.html "type tower_http::BoxError") Alias for a type-erased error type. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/propagate_header/ # Path: propagate_header/ [tower_http](../index.html) # Module propagate_header Copy item path [Source](../../src/tower_http/propagate_header.rs.html#1-154) Available on **crate feature`propagate-header`** only. Expand description Propagate a header from the request to the response. ## §Example use http::{Request, Response, header::HeaderName}; use std::convert::Infallible; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use tower_http::propagate_header::PropagateHeaderLayer; use bytes::Bytes; use http_body_util::Full; async fn handle(req: Request>) -> Result>, Infallible> { // ... } let mut svc = ServiceBuilder::new() // This will copy `x-request-id` headers from requests onto responses. .layer(PropagateHeaderLayer::new(HeaderName::from_static("x-request-id"))) .service_fn(handle); // Call the service. let request = Request::builder() .header("x-request-id", "1337") .body(Full::default())?; let response = svc.ready().await?.call(request).await?; assert_eq!(response.headers()["x-request-id"], "1337"); ## Structs§ [PropagateHeader](struct.PropagateHeader.html "struct tower_http::propagate_header::PropagateHeader") Middleware that propagates headers from requests to responses. [PropagateHeaderLayer](struct.PropagateHeaderLayer.html "struct tower_http::propagate_header::PropagateHeaderLayer") Layer that applies [`PropagateHeader`](struct.PropagateHeader.html "struct tower_http::propagate_header::PropagateHeader") which propagates headers from requests to responses. [ResponseFuture](struct.ResponseFuture.html "struct tower_http::propagate_header::ResponseFuture") Response future for [`PropagateHeader`](struct.PropagateHeader.html "struct tower_http::propagate_header::PropagateHeader"). --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/request_id/ # Path: request_id/ [tower_http](../index.html) # Module request_id Copy item path [Source](../../src/tower_http/request_id.rs.html#1-604) Available on **crate feature`request-id`** only. Expand description Set and propagate request ids. ## §Example use http::{Request, Response, header::HeaderName}; use tower::{Service, ServiceExt, ServiceBuilder}; use tower_http::request_id::{ SetRequestIdLayer, PropagateRequestIdLayer, MakeRequestId, RequestId, }; use http_body_util::Full; use bytes::Bytes; use std::sync::{Arc, atomic::{AtomicU64, Ordering}}; // A `MakeRequestId` that increments an atomic counter #[derive(Clone, Default)] struct MyMakeRequestId { counter: Arc, } impl MakeRequestId for MyMakeRequestId { fn make_request_id(&mut self, request: &Request) -> Option { let request_id = self.counter .fetch_add(1, Ordering::SeqCst) .to_string() .parse() .unwrap(); Some(RequestId::new(request_id)) } } let x_request_id = HeaderName::from_static("x-request-id"); let mut svc = ServiceBuilder::new() // set `x-request-id` header on all requests .layer(SetRequestIdLayer::new( x_request_id.clone(), MyMakeRequestId::default(), )) // propagate `x-request-id` headers from request to response .layer(PropagateRequestIdLayer::new(x_request_id)) .service(handler); let request = Request::new(Full::default()); let response = svc.ready().await?.call(request).await?; assert_eq!(response.headers()["x-request-id"], "0"); Additional convenience methods are available on [`ServiceBuilderExt`](../trait.ServiceBuilderExt.html "trait tower_http::ServiceBuilderExt"): use tower_http::ServiceBuilderExt; let mut svc = ServiceBuilder::new() .set_x_request_id(MyMakeRequestId::default()) .propagate_x_request_id() .service(handler); let request = Request::new(Full::default()); let response = svc.ready().await?.call(request).await?; assert_eq!(response.headers()["x-request-id"], "0"); See [`SetRequestId`](struct.SetRequestId.html "struct tower_http::request_id::SetRequestId") and [`PropagateRequestId`](struct.PropagateRequestId.html "struct tower_http::request_id::PropagateRequestId") for more details. ## §Using `Trace` To have request ids show up correctly in logs produced by [`Trace`](../trace/struct.Trace.html "struct tower_http::trace::Trace") you must apply the layers in this order: use tower_http::{ ServiceBuilderExt, trace::{TraceLayer, DefaultMakeSpan, DefaultOnResponse}, }; let svc = ServiceBuilder::new() // make sure to set request ids before the request reaches `TraceLayer` .set_x_request_id(MyMakeRequestId::default()) // log requests and responses .layer( TraceLayer::new_for_http() .make_span_with(DefaultMakeSpan::new().include_headers(true)) .on_response(DefaultOnResponse::new().include_headers(true)) ) // propagate the header to the response before the response reaches `TraceLayer` .propagate_x_request_id() .service(handler); ## §Doesn’t override existing headers [`SetRequestId`](struct.SetRequestId.html "struct tower_http::request_id::SetRequestId") and [`PropagateRequestId`](struct.PropagateRequestId.html "struct tower_http::request_id::PropagateRequestId") wont override request ids if its already present on requests or responses. Among other things, this allows other middleware to conditionally set request ids and use the middleware in this module as a fallback. ## Structs§ [MakeRequestUuid](struct.MakeRequestUuid.html "struct tower_http::request_id::MakeRequestUuid") A [`MakeRequestId`](trait.MakeRequestId.html "trait tower_http::request_id::MakeRequestId") that generates `UUID`s. [PropagateRequestId](struct.PropagateRequestId.html "struct tower_http::request_id::PropagateRequestId") Propagate request ids from requests to responses. [PropagateRequestIdLayer](struct.PropagateRequestIdLayer.html "struct tower_http::request_id::PropagateRequestIdLayer") Propagate request ids from requests to responses. [PropagateRequestIdResponseFuture](struct.PropagateRequestIdResponseFuture.html "struct tower_http::request_id::PropagateRequestIdResponseFuture") Response future for [`PropagateRequestId`](struct.PropagateRequestId.html "struct tower_http::request_id::PropagateRequestId"). [RequestId](struct.RequestId.html "struct tower_http::request_id::RequestId") An identifier for a request. [SetRequestId](struct.SetRequestId.html "struct tower_http::request_id::SetRequestId") Set request id headers and extensions on requests. [SetRequestIdLayer](struct.SetRequestIdLayer.html "struct tower_http::request_id::SetRequestIdLayer") Set request id headers and extensions on requests. ## Traits§ [MakeRequestId](trait.MakeRequestId.html "trait tower_http::request_id::MakeRequestId") Trait for producing [`RequestId`](struct.RequestId.html "struct tower_http::request_id::RequestId")s. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/sensitive_headers/ # Path: sensitive_headers/ [tower_http](../index.html) # Module sensitive_headers Copy item path [Source](../../src/tower_http/sensitive_headers.rs.html#1-448) Available on **crate feature`sensitive-headers`** only. Expand description Middlewares that mark headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). ## §Example use tower_http::sensitive_headers::SetSensitiveHeadersLayer; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use http::{Request, Response, header::AUTHORIZATION}; use http_body_util::Full; use bytes::Bytes; use std::{iter::once, convert::Infallible}; async fn handle(req: Request>) -> Result>, Infallible> { // ... } let mut service = ServiceBuilder::new() // Mark the `Authorization` header as sensitive so it doesn't show in logs // // `SetSensitiveHeadersLayer` will mark the header as sensitive on both the // request and response. // // The middleware is constructed from an iterator of headers to easily mark // multiple headers at once. .layer(SetSensitiveHeadersLayer::new(once(AUTHORIZATION))) .service(service_fn(handle)); // Call the service. let response = service .ready() .await? .call(Request::new(Full::default())) .await?; Its important to think about the order in which requests and responses arrive at your middleware. For example to hide headers both on requests and responses when using [`TraceLayer`](../trace/struct.TraceLayer.html "struct tower_http::trace::TraceLayer") you have to apply [`SetSensitiveRequestHeadersLayer`](struct.SetSensitiveRequestHeadersLayer.html "struct tower_http::sensitive_headers::SetSensitiveRequestHeadersLayer") before [`TraceLayer`](../trace/struct.TraceLayer.html "struct tower_http::trace::TraceLayer") and [`SetSensitiveResponseHeadersLayer`](struct.SetSensitiveResponseHeadersLayer.html "struct tower_http::sensitive_headers::SetSensitiveResponseHeadersLayer") afterwards. use tower_http::{ trace::TraceLayer, sensitive_headers::{ SetSensitiveRequestHeadersLayer, SetSensitiveResponseHeadersLayer, }, }; use tower::{Service, ServiceExt, ServiceBuilder, service_fn}; use http::header; use std::sync::Arc; let headers: Arc<[_]> = Arc::new([ header::AUTHORIZATION, header::PROXY_AUTHORIZATION, header::COOKIE, header::SET_COOKIE, ]); let service = ServiceBuilder::new() .layer(SetSensitiveRequestHeadersLayer::from_shared(Arc::clone(&headers))) .layer(TraceLayer::new_for_http()) .layer(SetSensitiveResponseHeadersLayer::from_shared(headers)) .service_fn(handle); ## Structs§ [SetSensitiveHeadersLayer](struct.SetSensitiveHeadersLayer.html "struct tower_http::sensitive_headers::SetSensitiveHeadersLayer") Mark headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive) on both requests and responses. [SetSensitiveRequestHeaders](struct.SetSensitiveRequestHeaders.html "struct tower_http::sensitive_headers::SetSensitiveRequestHeaders") Mark request headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). [SetSensitiveRequestHeadersLayer](struct.SetSensitiveRequestHeadersLayer.html "struct tower_http::sensitive_headers::SetSensitiveRequestHeadersLayer") Mark request headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). [SetSensitiveResponseHeaders](struct.SetSensitiveResponseHeaders.html "struct tower_http::sensitive_headers::SetSensitiveResponseHeaders") Mark response headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). [SetSensitiveResponseHeadersLayer](struct.SetSensitiveResponseHeadersLayer.html "struct tower_http::sensitive_headers::SetSensitiveResponseHeadersLayer") Mark response headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive). [SetSensitiveResponseHeadersResponseFuture](struct.SetSensitiveResponseHeadersResponseFuture.html "struct tower_http::sensitive_headers::SetSensitiveResponseHeadersResponseFuture") Response future for [`SetSensitiveResponseHeaders`](struct.SetSensitiveResponseHeaders.html "struct tower_http::sensitive_headers::SetSensitiveResponseHeaders"). ## Type Aliases§ [SetSensitiveHeaders](type.SetSensitiveHeaders.html "type tower_http::sensitive_headers::SetSensitiveHeaders") Mark headers as [sensitive](https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive) on both requests and responses. --- # Source: https://docs.rs/tower-http/latest/tower_http/set_header/ [tower_http](../index.html) # Module set_header Copy item path [Source](../../src/tower_http/set_header/mod.rs.html#1-110) Available on **crate feature set-header** only. Expand description Middleware for setting headers on requests and responses. See request and response for more details. ## Modules§ [request](request/index.html) Set a header on the request. [response](response/index.html) Set a header on the response. ## Structs§ [SetRequestHeader](struct.SetRequestHeader.html) Middleware that sets a header on the request. [SetRequestHeaderLayer](struct.SetRequestHeaderLayer.html) Layer that applies [SetRequestHeader](struct.SetRequestHeader.html) which adds a request header. [SetResponseHeader](struct.SetResponseHeader.html) Middleware that sets a header on the response. [SetResponseHeaderLayer](struct.SetResponseHeaderLayer.html) Layer that applies [SetResponseHeader](struct.SetResponseHeader.html) which adds a response header. ## Traits§ [MakeHeaderValue](trait.MakeHeaderValue.html) Trait for producing header values. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/timeout/ # Path: timeout/ [tower_http](../index.html) # Module timeout Copy item path [Source](../../src/tower_http/timeout/mod.rs.html#1-50) Available on **crate feature`timeout`** only. Expand description Middleware that applies a timeout to requests. If the request does not complete within the specified timeout, it will be aborted and a response with an empty body and a custom status code will be returned. ## §Differences from `tower::timeout` tower’s [`Timeout`](tower::timeout::Timeout) middleware uses an error to signal timeout, i.e. it changes the error type to [`BoxError`](https://docs.rs/tower/0.5.2/x86_64-unknown-linux- gnu/tower/type.BoxError.html "type tower::BoxError"). For HTTP services that is rarely what you want as returning errors will terminate the connection without sending a response. This middleware won’t change the error type and instead returns a response with an empty body and the specified status code. That means if your service’s error type is [`Infallible`](https://doc.rust- lang.org/nightly/core/convert/enum.Infallible.html "enum core::convert::Infallible"), it will still be [`Infallible`](https://doc.rust- lang.org/nightly/core/convert/enum.Infallible.html "enum core::convert::Infallible") after applying this middleware. ## §Example use http::{Request, Response, StatusCode}; use http_body_util::Full; use bytes::Bytes; use std::{convert::Infallible, time::Duration}; use tower::ServiceBuilder; use tower_http::timeout::TimeoutLayer; async fn handle(_: Request>) -> Result>, Infallible> { // ... } let svc = ServiceBuilder::new() // Timeout requests after 30 seconds with the specified status code .layer(TimeoutLayer::with_status_code(StatusCode::REQUEST_TIMEOUT, Duration::from_secs(30))) .service_fn(handle); ## Structs§ [RequestBodyTimeout](struct.RequestBodyTimeout.html "struct tower_http::timeout::RequestBodyTimeout") Applies a [`TimeoutBody`](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody") to the request body. [RequestBodyTimeoutLayer](struct.RequestBodyTimeoutLayer.html "struct tower_http::timeout::RequestBodyTimeoutLayer") Applies a [`TimeoutBody`](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody") to the request body. [ResponseBodyTimeout](struct.ResponseBodyTimeout.html "struct tower_http::timeout::ResponseBodyTimeout") Applies a [`TimeoutBody`](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody") to the response body. [ResponseBodyTimeoutLayer](struct.ResponseBodyTimeoutLayer.html "struct tower_http::timeout::ResponseBodyTimeoutLayer") Applies a [`TimeoutBody`](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody") to the response body. [Timeout](struct.Timeout.html "struct tower_http::timeout::Timeout") Middleware which apply a timeout to requests. [TimeoutBody](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody") Middleware that applies a timeout to request and response bodies. [TimeoutError](struct.TimeoutError.html "struct tower_http::timeout::TimeoutError") Error for [`TimeoutBody`](struct.TimeoutBody.html "struct tower_http::timeout::TimeoutBody"). [TimeoutLayer](struct.TimeoutLayer.html "struct tower_http::timeout::TimeoutLayer") Layer that applies the [`Timeout`](struct.Timeout.html "struct tower_http::timeout::Timeout") middleware which apply a timeout to requests. --- # Tower-HTTP Documentation # Source: https://docs.rs/tower-http/latest/tower_http/trace/ # Path: trace/ [tower_http](../index.html) # Module trace Copy item path [Source](../../src/tower_http/trace/mod.rs.html#1-635) Available on **crate feature`trace`** only. Expand description Middleware that adds high level [tracing](https://crates.io/crates/tracing) to a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux- gnu/tower_service/trait.Service.html "trait tower_service::Service"). ## §Example Adding tracing to your service can be as simple as: use http::{Request, Response}; use tower::{ServiceBuilder, ServiceExt, Service}; use tower_http::trace::TraceLayer; use std::convert::Infallible; use http_body_util::Full; use bytes::Bytes; async fn handle(request: Request>) -> Result>, Infallible> { Ok(Response::new(Full::default())) } // Setup tracing tracing_subscriber::fmt::init(); let mut service = ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .service_fn(handle); let request = Request::new(Full::from("foo")); let response = service .ready() .await? .call(request) .await?; If you run this application with `RUST_LOG=tower_http=trace cargo run` you should see logs like: Mar 05 20:50:28.523 DEBUG request{method=GET path="/foo"}: tower_http::trace::on_request: started processing request Mar 05 20:50:28.524 DEBUG request{method=GET path="/foo"}: tower_http::trace::on_response: finished processing request latency=1 ms status=200 ## §Customization [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") comes with good defaults but also supports customizing many aspects of the output. The default behaviour supports some customization: use http::{Request, Response, HeaderMap, StatusCode}; use http_body_util::Full; use bytes::Bytes; use tower::ServiceBuilder; use tracing::Level; use tower_http::{ LatencyUnit, trace::{TraceLayer, DefaultMakeSpan, DefaultOnRequest, DefaultOnResponse}, }; use std::time::Duration; let service = ServiceBuilder::new() .layer( TraceLayer::new_for_http() .make_span_with( DefaultMakeSpan::new().include_headers(true) ) .on_request( DefaultOnRequest::new().level(Level::INFO) ) .on_response( DefaultOnResponse::new() .level(Level::INFO) .latency_unit(LatencyUnit::Micros) ) // on so on for `on_eos`, `on_body_chunk`, and `on_failure` ) .service_fn(handle); However for maximum control you can provide callbacks: use http::{Request, Response, HeaderMap, StatusCode}; use http_body_util::Full; use bytes::Bytes; use tower::ServiceBuilder; use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer}; use std::time::Duration; use tracing::Span; let service = ServiceBuilder::new() .layer( TraceLayer::new_for_http() .make_span_with(|request: &Request>| { tracing::debug_span!("http-request") }) .on_request(|request: &Request>, _span: &Span| { tracing::debug!("started {} {}", request.method(), request.uri().path()) }) .on_response(|response: &Response>, latency: Duration, _span: &Span| { tracing::debug!("response generated in {:?}", latency) }) .on_body_chunk(|chunk: &Bytes, latency: Duration, _span: &Span| { tracing::debug!("sending {} bytes", chunk.len()) }) .on_eos(|trailers: Option<&HeaderMap>, stream_duration: Duration, _span: &Span| { tracing::debug!("stream closed after {:?}", stream_duration) }) .on_failure(|error: ServerErrorsFailureClass, latency: Duration, _span: &Span| { tracing::debug!("something went wrong") }) ) .service_fn(handle); ### §Disabling something Setting the behaviour to `()` will be disable that particular step: use http::StatusCode; use tower::ServiceBuilder; use tower_http::{classify::ServerErrorsFailureClass, trace::TraceLayer}; use std::time::Duration; use tracing::Span; let service = ServiceBuilder::new() .layer( // This configuration will only emit events on failures TraceLayer::new_for_http() .on_request(()) .on_response(()) .on_body_chunk(()) .on_eos(()) .on_failure(|error: ServerErrorsFailureClass, latency: Duration, _span: &Span| { tracing::debug!("something went wrong") }) ) .service_fn(handle); ## §When the callbacks are called #### §`on_request` The `on_request` callback is called when the request arrives at the middleware in [`Service::call`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux- gnu/tower_service/trait.Service.html#tymethod.call "method tower_service::Service::call") just prior to passing the request to the inner service. #### §`on_response` The `on_response` callback is called when the inner service’s response future completes with `Ok(response)` regardless if the response is classified as a success or a failure. For example if you’re using [`ServerErrorsAsFailures`](../classify/struct.ServerErrorsAsFailures.html "struct tower_http::classify::ServerErrorsAsFailures") as your classifier and the inner service responds with `500 Internal Server Error` then the `on_response` callback is still called. `on_failure` would _also_ be called in this case since the response was classified as a failure. #### §`on_body_chunk` The `on_body_chunk` callback is called when the response body produces a new chunk, that is when [`Body::poll_frame`](https://docs.rs/http- body/1.0.1/x86_64-unknown-linux- gnu/http_body/trait.Body.html#tymethod.poll_frame "method http_body::Body::poll_frame") returns a data frame. `on_body_chunk` is called even if the chunk is empty. #### §`on_eos` The `on_eos` callback is called when a streaming response body ends, that is when [`Body::poll_frame`](https://docs.rs/http-body/1.0.1/x86_64-unknown- linux-gnu/http_body/trait.Body.html#tymethod.poll_frame "method http_body::Body::poll_frame") returns a trailers frame. `on_eos` is called even if the trailers produced are `None`. #### §`on_failure` The `on_failure` callback is called when: * The inner [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service")’s response future resolves to an error. * A response is classified as a failure. * [`Body::poll_frame`](https://docs.rs/http-body/1.0.1/x86_64-unknown-linux-gnu/http_body/trait.Body.html#tymethod.poll_frame "method http_body::Body::poll_frame") returns an error. * An end-of-stream is classified as a failure. ## §Recording fields on the span All callbacks receive a reference to the [tracing](https://crates.io/crates/tracing) [`Span`](https://docs.rs/tracing/0.1.40/x86_64-unknown-linux- gnu/tracing/span/struct.Span.html "struct tracing::span::Span"), corresponding to this request, produced by the closure passed to [`TraceLayer::make_span_with`](struct.TraceLayer.html#method.make_span_with "method tower_http::trace::TraceLayer::make_span_with"). It can be used to [record field values](https://docs.rs/tracing/latest/tracing/span/struct.Span.html#method.record) that weren’t known when the span was created. use http::{Request, Response, HeaderMap, StatusCode}; use http_body_util::Full; use bytes::Bytes; use tower::ServiceBuilder; use tower_http::trace::TraceLayer; use tracing::Span; use std::time::Duration; let service = ServiceBuilder::new() .layer( TraceLayer::new_for_http() .make_span_with(|request: &Request>| { tracing::debug_span!( "http-request", status_code = tracing::field::Empty, ) }) .on_response(|response: &Response>, _latency: Duration, span: &Span| { span.record("status_code", &tracing::field::display(response.status())); tracing::debug!("response generated") }) ) .service_fn(handle); ## §Providing classifiers Tracing requires determining if a response is a success or failure. [`MakeClassifier`](../classify/trait.MakeClassifier.html "trait tower_http::classify::MakeClassifier") is used to create a classifier for the incoming request. See the docs for [`MakeClassifier`](../classify/trait.MakeClassifier.html "trait tower_http::classify::MakeClassifier") and [`ClassifyResponse`](../classify/trait.ClassifyResponse.html "trait tower_http::classify::ClassifyResponse") for more details on classification. A [`MakeClassifier`](../classify/trait.MakeClassifier.html "trait tower_http::classify::MakeClassifier") can be provided when creating a [`TraceLayer`](struct.TraceLayer.html "struct tower_http::trace::TraceLayer"): use http::{Request, Response}; use http_body_util::Full; use bytes::Bytes; use tower::ServiceBuilder; use tower_http::{ trace::TraceLayer, classify::{ MakeClassifier, ClassifyResponse, ClassifiedResponse, NeverClassifyEos, SharedClassifier, }, }; use std::convert::Infallible; // Our `MakeClassifier` that always crates `MyClassifier` classifiers. #[derive(Copy, Clone)] struct MyMakeClassify; impl MakeClassifier for MyMakeClassify { type Classifier = MyClassifier; type FailureClass = &'static str; type ClassifyEos = NeverClassifyEos<&'static str>; fn make_classifier(&self, req: &Request) -> Self::Classifier { MyClassifier } } // A classifier that classifies failures as `"something went wrong..."`. #[derive(Copy, Clone)] struct MyClassifier; impl ClassifyResponse for MyClassifier { type FailureClass = &'static str; type ClassifyEos = NeverClassifyEos<&'static str>; fn classify_response( self, res: &Response ) -> ClassifiedResponse { // Classify based on the status code. if res.status().is_server_error() { ClassifiedResponse::Ready(Err("something went wrong...")) } else { ClassifiedResponse::Ready(Ok(())) } } fn classify_error(self, error: &E) -> Self::FailureClass where E: std::fmt::Display + 'static, { "something went wrong..." } } let service = ServiceBuilder::new() // Create a trace layer that uses our classifier. .layer(TraceLayer::new(MyMakeClassify)) .service_fn(handle); // Since `MyClassifier` is `Clone` we can also use `SharedClassifier` // to avoid having to define a separate `MakeClassifier`. let service = ServiceBuilder::new() .layer(TraceLayer::new(SharedClassifier::new(MyClassifier))) .service_fn(handle); [`TraceLayer`](struct.TraceLayer.html "struct tower_http::trace::TraceLayer") comes with convenience methods for using common classifiers: * [`TraceLayer::new_for_http`](struct.TraceLayer.html#method.new_for_http "associated function tower_http::trace::TraceLayer::new_for_http") classifies based on the status code. It doesn’t consider streaming responses. * [`TraceLayer::new_for_grpc`](struct.TraceLayer.html#method.new_for_grpc "associated function tower_http::trace::TraceLayer::new_for_grpc") classifies based on the gRPC protocol and supports streaming responses. ## Structs§ [DefaultMakeSpan](struct.DefaultMakeSpan.html "struct tower_http::trace::DefaultMakeSpan") The default way [`Span`](https://docs.rs/tracing/0.1.40/x86_64-unknown-linux-gnu/tracing/span/struct.Span.html "struct tracing::span::Span")s will be created for [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [DefaultOnBodyChunk](struct.DefaultOnBodyChunk.html "struct tower_http::trace::DefaultOnBodyChunk") The default [`OnBodyChunk`](trait.OnBodyChunk.html "trait tower_http::trace::OnBodyChunk") implementation used by [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [DefaultOnEos](struct.DefaultOnEos.html "struct tower_http::trace::DefaultOnEos") The default [`OnEos`](trait.OnEos.html "trait tower_http::trace::OnEos") implementation used by [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [DefaultOnFailure](struct.DefaultOnFailure.html "struct tower_http::trace::DefaultOnFailure") The default [`OnFailure`](trait.OnFailure.html "trait tower_http::trace::OnFailure") implementation used by [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [DefaultOnRequest](struct.DefaultOnRequest.html "struct tower_http::trace::DefaultOnRequest") The default [`OnRequest`](trait.OnRequest.html "trait tower_http::trace::OnRequest") implementation used by [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [DefaultOnResponse](struct.DefaultOnResponse.html "struct tower_http::trace::DefaultOnResponse") The default [`OnResponse`](trait.OnResponse.html "trait tower_http::trace::OnResponse") implementation used by [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [ResponseBody](struct.ResponseBody.html "struct tower_http::trace::ResponseBody") Response body for [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [ResponseFuture](struct.ResponseFuture.html "struct tower_http::trace::ResponseFuture") Response future for [`Trace`](struct.Trace.html "struct tower_http::trace::Trace"). [Trace](struct.Trace.html "struct tower_http::trace::Trace") Middleware that adds high level [tracing](https://crates.io/crates/tracing) to a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service"). [TraceLayer](struct.TraceLayer.html "struct tower_http::trace::TraceLayer") [`Layer`](https://docs.rs/tower-layer/0.3.3/x86_64-unknown-linux-gnu/tower_layer/trait.Layer.html "trait tower_layer::Layer") that adds high level [tracing](https://crates.io/crates/tracing) to a [`Service`](https://docs.rs/tower-service/0.3.3/x86_64-unknown-linux-gnu/tower_service/trait.Service.html "trait tower_service::Service"). ## Traits§ [MakeSpan](trait.MakeSpan.html "trait tower_http::trace::MakeSpan") Trait used to generate [`Span`](https://docs.rs/tracing/0.1.40/x86_64-unknown-linux-gnu/tracing/span/struct.Span.html "struct tracing::span::Span")s from requests. [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") wraps all request handling in this span. [OnBodyChunk](trait.OnBodyChunk.html "trait tower_http::trace::OnBodyChunk") Trait used to tell [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") what to do when a body chunk has been sent. [OnEos](trait.OnEos.html "trait tower_http::trace::OnEos") Trait used to tell [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") what to do when a stream closes. [OnFailure](trait.OnFailure.html "trait tower_http::trace::OnFailure") Trait used to tell [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") what to do when a request fails. [OnRequest](trait.OnRequest.html "trait tower_http::trace::OnRequest") Trait used to tell [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") what to do when a request is received. [OnResponse](trait.OnResponse.html "trait tower_http::trace::OnResponse") Trait used to tell [`Trace`](struct.Trace.html "struct tower_http::trace::Trace") what to do when a response has been produced. ## Type Aliases§ [GrpcMakeClassifier](type.GrpcMakeClassifier.html "type tower_http::trace::GrpcMakeClassifier") MakeClassifier for gRPC requests. [HttpMakeClassifier](type.HttpMakeClassifier.html "type tower_http::trace::HttpMakeClassifier") MakeClassifier for HTTP requests.