### Redirect Service Example Source: https://docs.rs/tower-http/latest/tower_http/services/redirect/index.html This example demonstrates how to use the `Redirect` service to permanently redirect HTTP requests to HTTPS. ```APIDOC ## Redirect Service Service that redirects all requests. ### Example ```rust use http::{Request, Uri, StatusCode}; use http_body_util::Full; use bytes::Bytes; use tower::{Service, ServiceExt}; use tower_http::services::Redirect; let uri: Uri = "https://example.com/".parse().unwrap(); let mut service: Redirect> = Redirect::permanent(uri); let request = Request::builder() .uri("http://example.com") .body(Full::::default()) .unwrap(); let response = service.oneshot(request).await?; assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT); assert_eq!(response.headers()["location"], "https://example.com/"); ``` ### Structs #### Redirect Service that redirects all requests. #### ResponseFuture Response future of `Redirect`. ``` -------------------------------- ### CompressionLayer Usage Example Source: https://docs.rs/tower-http/latest/tower_http/compression/index.html This example demonstrates how to use the `CompressionLayer` to compress response bodies based on the `Accept-Encoding` header. It shows setting up a service that handles file content and compresses it before sending it back to the client. ```APIDOC ## CompressionLayer Compress response bodies of the underlying service. ### Example Example showing how to respond with the compressed contents of a file. ```rust 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); ``` ``` -------------------------------- ### Example Usage Source: https://docs.rs/tower-http/latest/tower_http/classify/struct.StatusInRangeAsFailures.html A client with tracing where server errors and client errors are considered failures. ```APIDOC ## Example A client with tracing where server errors _and_ client errors are considered failures. ```rust use tower_http::{trace::TraceLayer, classify::StatusInRangeAsFailures}; use tower::{ServiceBuilder, Service, ServiceExt}; use http::{Request, Method}; use http_body_util::Full; use bytes::Bytes; use hyper_util::{rt::TokioExecutor, client::legacy::Client}; let classifier = StatusInRangeAsFailures::new(400..=599); let client = Client::builder(TokioExecutor::new()).build_http(); let mut client = ServiceBuilder::new() .layer(TraceLayer::new(classifier.into_make_classifier())) .service(client); let request = Request::builder() .method(Method::GET) .uri("https://example.com") .body(Full::::default()) .unwrap(); let response = client.ready().await?.call(request).await?; ``` ``` -------------------------------- ### Example Usage of ServiceBuilderExt Source: https://docs.rs/tower-http/latest/tower_http/trait.ServiceBuilderExt.html Demonstrates how to use ServiceBuilderExt methods like timeout, trace_for_http, and propagate_header to configure a service. Ensure the 'util' feature flag is enabled for these methods. ```rust use http::{Request, Response, header::HeaderName}; use bytes::Bytes; use http_body_util::Full; use std::{time::Duration, convert::Infallible}; use tower::{ServiceBuilder, ServiceExt, Service}; use tower_http::ServiceBuilderExt; async fn handle(request: Request>) -> Result>, Infallible> { Ok(Response::new(Full::default())) } let service = ServiceBuilder::new() // Methods from tower .timeout(Duration::from_secs(30)) // Methods from tower-http .trace_for_http() .propagate_header(HeaderName::from_static("x-request-id")) .service_fn(handle); ``` -------------------------------- ### Basic HTTP Tracing Setup Source: https://docs.rs/tower-http/latest/tower_http/trace/index.html Demonstrates how to add the TraceLayer to a service for basic HTTP request and response logging. Ensure tracing is initialized (e.g., `tracing_subscriber::fmt::init()`) and run with `RUST_LOG=tower_http=trace` to see output. ```rust 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?; ``` -------------------------------- ### Permanent Redirect Example Source: https://docs.rs/tower-http/latest/tower_http/services/redirect/index.html Use this snippet to set up a permanent redirect. Ensure the `redirect` feature is enabled. ```rust use http::{Request, Uri, StatusCode}; use http_body_util::Full; use bytes::Bytes; use tower::{Service, ServiceExt}; use tower_http::services::Redirect; let uri: Uri = "https://example.com/".parse().unwrap(); let mut service: Redirect> = Redirect::permanent(uri); let request = Request::builder() .uri("http://example.com") .body(Full::::default()) .unwrap(); let response = service.oneshot(request).await?; assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT); assert_eq!(response.headers()["location"], "https://example.com/"); ``` -------------------------------- ### FollowRedirect::get_ref Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/struct.FollowRedirect.html Gets a reference to the underlying service. ```APIDOC ## FollowRedirect::get_ref ### Description Gets a reference to the underlying service. ### Method ```rust pub fn get_ref(&self) -> &S ``` ``` -------------------------------- ### Build Tower-HTTP Client Middleware Stack Source: https://docs.rs/tower-http/latest/tower_http/index.html Illustrates applying tower-http middleware to an HTTP client. This example includes tracing with custom failure classification, setting a User-Agent header, and response decompression. ```rust 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(); } ``` -------------------------------- ### get_ref Source: https://docs.rs/tower-http/latest/tower_http/sensitive_headers/struct.SetSensitiveResponseHeaders.html Gets a reference to the underlying service. ```APIDOC #### pub fn get_ref(&self) -> &S Gets a reference to the underlying service. ``` -------------------------------- ### Example: Tracing client with StatusInRangeAsFailures Source: https://docs.rs/tower-http/latest/tower_http/classify/struct.StatusInRangeAsFailures.html Demonstrates using StatusInRangeAsFailures with TraceLayer to classify both client and server errors as failures in a tracing-enabled HTTP client. ```rust use tower_http::{trace::TraceLayer, classify::StatusInRangeAsFailures}; use tower::{ServiceBuilder, Service, ServiceExt}; use http::{Request, Method}; use http_body_util::Full; use bytes::Bytes; use hyper_util::{rt::TokioExecutor, client::legacy::Client}; let classifier = StatusInRangeAsFailures::new(400..=599); let client = Client::builder(TokioExecutor::new()).build_http(); let mut client = ServiceBuilder::new() .layer(TraceLayer::new(classifier.into_make_classifier())) .service(client); let request = Request::builder() .method(Method::GET) .uri("https://example.com") .body(Full::::default()) .unwrap(); let response = client.ready().await?.call(request).await?; ``` -------------------------------- ### AsyncRequireAuthorization::get_ref Source: https://docs.rs/tower-http/latest/tower_http/auth/async_require_authorization/struct.AsyncRequireAuthorization.html Gets a reference to the underlying service. ```APIDOC ## AsyncRequireAuthorization::get_ref ### Description Gets an immutable reference to the inner service wrapped by the middleware. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ### Returns A reference to the inner service. ``` -------------------------------- ### AddAuthorization::get_ref Source: https://docs.rs/tower-http/latest/tower_http/auth/add_authorization/struct.AddAuthorization.html Gets a reference to the underlying service. ```APIDOC ## AddAuthorization::get_ref ### Description Gets a reference to the underlying service. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ``` -------------------------------- ### Get Service When Ready (Oneshot) Source: https://docs.rs/tower-http/latest/tower_http/normalize_path/struct.NormalizePath.html Implements `ServiceExt::ready_oneshot`, which yields the service itself when it becomes ready to accept a request. This is a one-time operation. ```rust fn ready_oneshot(self) -> ReadyOneshot ``` -------------------------------- ### FollowRedirect::get_mut Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/struct.FollowRedirect.html Gets a mutable reference to the underlying service. ```APIDOC ## FollowRedirect::get_mut ### Description Gets a mutable reference to the underlying service. ### Method ```rust pub fn get_mut(&mut self) -> &mut S ``` ``` -------------------------------- ### Compressing File Contents with CompressionLayer Source: https://docs.rs/tower-http/latest/tower_http/compression/index.html Use CompressionLayer to compress response bodies. This example demonstrates compressing the contents of a file and verifying that the compressed body is smaller than the original. Ensure the necessary crate features (`compression-br`, `compression-deflate`, `compression-gzip`, or `compression-zstd`) are enabled. ```rust 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); ``` -------------------------------- ### Add Extension Layer Example Source: https://docs.rs/tower-http/latest/tower_http/add_extension/index.html Demonstrates how to use `AddExtensionLayer` to share an `Arc` with all requests. The shared state is then retrieved from the request extensions within the handler. ```rust 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?; ``` -------------------------------- ### FutureExt::flatten Example Source: https://docs.rs/tower-http/latest/tower_http/limit/struct.ResponseFuture.html Demonstrates flattening a future whose output is another future using the `flatten` combinator from `FutureExt`. ```rust fn flatten(self) -> Flatten where Self::Output: Future, Self: Sized, ``` -------------------------------- ### AsyncRequireAuthorizationLayer with a closure Source: https://docs.rs/tower-http/latest/tower_http/auth/async_require_authorization/index.html This example shows how to use `AsyncRequireAuthorizationLayer` with a closure that performs the authorization logic. ```APIDOC ## Module async_require_authorization tower_http::auth ## Structs ### AsyncRequireAuthorizationLayer Layer that applies `AsyncRequireAuthorization` which authorizes all requests using the `Authorization` header. #### Example (using a closure) ```rust use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest}; use http::{Request, Response, StatusCode}; use tower::{Service, ServiceExt, ServiceBuilder, BoxError}; use futures_core::future::BoxFuture; use http_body_util::Full; use bytes::Bytes; async fn check_auth(request: &Request) -> Option { // ... implementation omitted for brevity unimplemented!(); } #[derive(Debug)] struct UserId(String); async fn handle(request: Request>) -> Result>, BoxError> { // ... implementation omitted for brevity unimplemented!(); } let service = ServiceBuilder::new() .layer(AsyncRequireAuthorizationLayer::new(|request: Request>| async move { if let Some(user_id) = check_auth(&request).await { Ok(request) } else { let unauthorized_response = Response::builder() .status(StatusCode::UNAUTHORIZED) .body(Full::::default()) .unwrap(); Err(unauthorized_response) } })) .service_fn(handle); ``` ``` -------------------------------- ### Customizing FollowRedirect Policy Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/index.html Illustrates how to customize the redirection policy using `PolicyExt`. This example sets a limit of 10 redirects, returns a custom error for too many redirects, and prevents following cross-origin redirects. ```rust 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); // ... ``` -------------------------------- ### Create ServeFile with Path Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Creates a new ServeFile instance. The Content-Type is automatically determined from the file extension. ```rust pub fn new>(path: P) -> Self ``` -------------------------------- ### TimeoutBody Example Source: https://docs.rs/tower-http/latest/tower_http/timeout/struct.TimeoutBody.html An example demonstrating how to use RequestBodyTimeoutLayer, which utilizes TimeoutBody, to apply a timeout to request bodies within a Tower service. ```APIDOC ## Example ```rust use http::{Request, Response}; use bytes::Bytes; use http_body_util::Full; use std::time::Duration; use tower::ServiceBuilder; use tower_http::timeout::RequestBodyTimeoutLayer; async fn handle(_: Request>) -> Result>, std::convert::Infallible> { // ... } let svc = ServiceBuilder::new() // Timeout bodies after 30 seconds of inactivity .layer(RequestBodyTimeoutLayer::new(Duration::from_secs(30))) .service_fn(handle); ``` ``` -------------------------------- ### Propagate Header Example Source: https://docs.rs/tower-http/latest/tower_http/propagate_header/index.html This example demonstrates how to use PropagateHeaderLayer to copy the 'x-request-id' header from a request to the response. Ensure the 'propagate-header' feature is enabled. ```rust 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"); ``` -------------------------------- ### Request Decompression Example Source: https://docs.rs/tower-http/latest/tower_http/decompression/index.html Demonstrates how to use `RequestDecompressionLayer` to automatically decompress incoming request bodies. The handler then receives the decompressed data. ```APIDOC ## Request Decompression ### Description Middleware that decompresses request bodies. ### Usage ```rust use tower_http::decompression::RequestDecompressionLayer; // Apply the layer to your service builder ServiceBuilder::new().layer(RequestDecompressionLayer::new()) ``` ### Example ```rust 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!"))) } ``` ``` -------------------------------- ### Configure and Use CORS Layer Source: https://docs.rs/tower-http/latest/tower_http/cors/index.html Demonstrates how to configure `CorsLayer` to allow specific HTTP methods and any origin, then applies it to a service. This setup is useful for enabling cross-origin requests to your HTTP service. ```rust use http::{Request, Response, Method, header}; use http_body_util::Full; use bytes::Bytes; use tower::{ServiceBuilder, Service, ServiceExt}; 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? // Note: The original example had a missing `?` here, which is now corrected. .call(request) .await?; assert_eq!( response.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap(), "*", ); ``` -------------------------------- ### Detecting a cyclic redirection Example Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/policy/trait.Policy.html An example implementation of the `Policy` trait to detect and stop cyclic redirections by keeping track of visited URIs. ```APIDOC ## §Example Detecting a cyclic redirection: ```rust use http::{Request, Uri}; use std::collections::HashSet; use tower_http::follow_redirect::policy::{Action, Attempt, Policy}; #[derive(Clone)] pub struct DetectCycle { uris: HashSet, } impl Policy for DetectCycle { fn redirect(&mut self, attempt: &Attempt<'_>) -> Result { if self.uris.contains(attempt.location()) { Ok(Action::Stop) } else { self.uris.insert(attempt.previous().clone()); Ok(Action::Follow) } } } ``` ``` -------------------------------- ### FutureExt::flatten_stream Example Source: https://docs.rs/tower-http/latest/tower_http/limit/struct.ResponseFuture.html Shows how to flatten a future whose output is a stream using the `flatten_stream` combinator from `FutureExt`. ```rust fn flatten_stream(self) -> FlattenStream where Self::Output: Stream, Self: Sized, ``` -------------------------------- ### CorsLayer Usage Example Source: https://docs.rs/tower-http/latest/tower_http/cors/index.html This example demonstrates how to configure and use the CorsLayer to add CORS headers to HTTP requests. It shows how to allow specific methods and origins, and how the middleware modifies the response. ```APIDOC ## CorsLayer Example ### Description This example demonstrates how to configure and use the `CorsLayer` to add CORS headers to HTTP requests. It shows how to allow specific methods and origins, and how the middleware modifies the response. ### Usage ```rust use http::{Request, Response, Method, header}; use http_body_util::Full; use bytes::Bytes; use tower::{ServiceBuilder, Service, ServiceExt}; 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(); // This is a simplified representation of calling the service. // In a real application, you would await `service.ready()` and then `call(request)`. // let response = service.ready().await?.call(request).await?; // Assert that the CORS header is present (example assertion) // assert_eq!( // response.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap(), // "*", // ); ``` ### Configuration Options - `CorsLayer::new()`: Initializes a new `CorsLayer`. - `.allow_methods([Method::GET, Method::POST])`: Configures the layer to allow `GET` and `POST` HTTP methods. - `.allow_origin(Any)`: Configures the layer to allow requests from any origin (`*`). ### Middleware Behavior When a request comes in, the `CorsLayer` inspects the `Origin` header. If the origin is allowed, it adds the `Access-Control-Allow-Origin` header (and potentially others like `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers`) to the response. The example shows an assertion for the `Access-Control-Allow-Origin` header being set to `*`. ``` -------------------------------- ### DefaultOnEos::new Source: https://docs.rs/tower-http/latest/tower_http/trace/struct.DefaultOnEos.html Creates a new instance of DefaultOnEos. ```APIDOC ## DefaultOnEos::new ### Description Creates a new `DefaultOnEos`. ### Method `new()` ### Returns `Self` (a new `DefaultOnEos` instance) ``` -------------------------------- ### Create ServeFile with Path and Mime Type Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Creates a new ServeFile instance with a specific MIME type. Panics if the provided MIME type is invalid. ```rust pub fn new_with_mime>(path: P, mime: &Mime) -> Self ``` -------------------------------- ### Manual Error Handling with ServeDir Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeDir.html Demonstrates how to manually handle errors from `ServeDir`'s `try_call` method, allowing custom responses for I/O errors. This example shows how to convert errors into an "Internal Server Error" response. ```rust use tower_http::services::ServeDir; use std::{io, convert::Infallible}; use http::{Request, Response, StatusCode}; use http_body::Body as _; use http_body_util::{Full, BodyExt, combinators::UnsyncBoxBody}; use bytes::Bytes; use tower::{service_fn, ServiceExt, BoxError}; async fn serve_dir( request: Request> ) -> Result>, Infallible> { let mut service = ServeDir::new("assets"); // You only need to worry about backpressure, and thus call `ServiceExt::ready`, if // your adding a fallback to `ServeDir` that cares about backpressure. // // Its shown here for demonstration but you can do `service.try_call(request)` // otherwise let ready_service = match ServiceExt::>>::ready(&mut service).await { Ok(ready_service) => ready_service, Err(infallible) => match infallible {{}}, }; match ready_service.try_call(request).await { Ok(response) => { Ok(response.map(|body| body.map_err(Into::into).boxed_unsync())) } Err(err) => { let body = Full::from("Something went wrong...") .map_err(Into::into) .boxed_unsync(); let response = Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) .body(body) .unwrap(); Ok(response) } } } ``` -------------------------------- ### Basic FollowRedirect Usage Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/index.html Demonstrates basic usage of `FollowRedirectLayer` to follow HTTP redirections. It shows how to create a service with the layer and make a request, then asserts the final request URI from the response extensions. ```rust 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/"); ``` -------------------------------- ### Trace::get_ref Source: https://docs.rs/tower-http/latest/tower_http/trace/struct.Trace.html Gets a reference to the underlying service. ```APIDOC ## Trace::get_ref ### Description Gets a reference to the underlying service. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ``` -------------------------------- ### Enable Precompressed Gzip Serving Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Configures ServeFile to look for a precompressed gzip version of the file. If the client supports gzip encoding and the `.gz` file exists, it will be served instead of the original file. ```rust pub fn precompressed_gzip(self) -> Self ``` -------------------------------- ### ResponseBodyTimeout::get_ref Source: https://docs.rs/tower-http/latest/tower_http/timeout/struct.ResponseBodyTimeout.html Gets a reference to the underlying service. ```APIDOC ## pub fn get_ref(&self) -> &S ### Description Gets a reference to the underlying service. ### Returns - &S - An immutable reference to the wrapped service. ``` -------------------------------- ### get_mut Source: https://docs.rs/tower-http/latest/tower_http/sensitive_headers/struct.SetSensitiveResponseHeaders.html Gets a mutable reference to the underlying service. ```APIDOC #### pub fn get_mut(&mut self) -> &mut S Gets a mutable reference to the underlying service. ``` -------------------------------- ### fn ready_oneshot(self) -> ReadyOneshot Source: https://docs.rs/tower-http/latest/tower_http/limit/struct.RequestBodyLimit.html Yields the service when it is ready to accept a request. ```APIDOC ## fn ready_oneshot(self) -> ReadyOneshot ### Description Yields the service when it is ready to accept a request. ### Method N/A (Method on self) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response - **ReadyOneshot** - The service when ready. ``` -------------------------------- ### RequestId::header_value Source: https://docs.rs/tower-http/latest/tower_http/request_id/struct.RequestId.html Gets a reference to the underlying `HeaderValue`. ```APIDOC ## RequestId::header_value ### Description Gets a reference to the underlying `HeaderValue`. ### Signature ```rust pub fn header_value(&self) -> &HeaderValue ``` ### Returns A reference to the `HeaderValue`. ``` -------------------------------- ### ServeFile::new Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Creates a new ServeFile instance. The Content-Type is automatically determined from the file extension. ```APIDOC ## ServeFile::new ### Description Create a new `ServeFile`. The `Content-Type` will be guessed from the file extension. ### Signature ```rust pub fn new>(path: P) -> Self ``` ### Parameters * `path`: The path to the file to serve. ``` -------------------------------- ### MapRequestBody::get_ref Source: https://docs.rs/tower-http/latest/tower_http/map_request_body/struct.MapRequestBody.html Gets a reference to the underlying service. ```APIDOC ## fn get_ref(&self) -> &S ### Description Gets a reference to the underlying service. ``` -------------------------------- ### Configuring Custom Predicates Source: https://docs.rs/tower-http/latest/tower_http/compression/predicate/struct.DefaultPredicate.html Build a custom predicate by combining existing types like SizeAbove and NotForContentType. This example sets a minimum size of 256 bytes and excludes gRPC, images, and JSON. ```rust use tower_http::compression::predicate::{SizeAbove, NotForContentType, Predicate}; // slightly large min size than the default 32 let predicate = SizeAbove::new(256) // still don't compress gRPC .and(NotForContentType::GRPC) // still don't compress images .and(NotForContentType::IMAGES) // also don't compress JSON .and(NotForContentType::const_new("application/json")); ``` -------------------------------- ### CompressionLayer::new Source: https://docs.rs/tower-http/latest/tower_http/compression/struct.CompressionLayer.html Creates a new CompressionLayer with default settings. ```APIDOC ## CompressionLayer::new ### Description Creates a new `CompressionLayer`. ### Method `new()` ### Returns - `Self`: A new instance of `CompressionLayer`. ``` -------------------------------- ### fn ready(&mut self) -> Ready<'_, Self, Request> Source: https://docs.rs/tower-http/latest/tower_http/limit/struct.RequestBodyLimit.html Yields a mutable reference to the service when it is ready to accept a request. ```APIDOC ## fn ready(&mut self) -> Ready<'_, Self, Request> ### Description Yields a mutable reference to the service when it is ready to accept a request. ### Method N/A (Method on self) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response - **Ready<'_, Self, Request>** - A mutable reference to the service when ready. ``` -------------------------------- ### RequestDecompression::get_ref Source: https://docs.rs/tower-http/latest/tower_http/decompression/struct.RequestDecompression.html Gets a reference to the underlying service. ```APIDOC ## RequestDecompression::get_ref ### Description Gets a reference to the underlying service. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ``` -------------------------------- ### Enable Precompressed Deflate Serving Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Configures ServeFile to look for a precompressed deflate version of the file. If the client supports deflate encoding and the `.zz` file exists, it will be served instead of the original file. ```rust pub fn precompressed_deflate(self) -> Self ``` -------------------------------- ### Service Readiness and Execution Source: https://docs.rs/tower-http/latest/tower_http/trace/struct.Trace.html Methods for managing service readiness and executing requests. `ready` yields a mutable reference when the service is ready, `ready_oneshot` yields the service when ready, and `oneshot` consumes the service to execute a single request. ```APIDOC ## fn ready(&mut self) -> Ready<'_, Self, Request> ### Description Yields a mutable reference to the service when it is ready to accept a request. ## fn ready_oneshot(self) -> ReadyOneshot ### Description Yields the service when it is ready to accept a request. ## fn oneshot(self, req: Request) -> Oneshot ### Description Consume this `Service`, calling it with the provided request once it is ready. ``` -------------------------------- ### Create a new ServeDir service Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeDir.html Instantiate ServeDir to serve files from the specified directory. This service will serve files from the given path and its subdirectories. ```rust use tower_http::services::ServeDir; // This will serve files in the "assets" directory and // its subdirectories let service = ServeDir::new("assets"); ``` -------------------------------- ### Trace::get_mut Source: https://docs.rs/tower-http/latest/tower_http/trace/struct.Trace.html Gets a mutable reference to the underlying service. ```APIDOC ## Trace::get_mut ### Description Gets a mutable reference to the underlying service. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ``` -------------------------------- ### Enable Precompressed Brotli Serving Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Configures ServeFile to look for a precompressed brotli version of the file. If the client supports brotli encoding and the `.br` file exists, it will be served instead of the original file. ```rust pub fn precompressed_br(self) -> Self ``` -------------------------------- ### ResponseBodyTimeout::get_mut Source: https://docs.rs/tower-http/latest/tower_http/timeout/struct.ResponseBodyTimeout.html Gets a mutable reference to the underlying service. ```APIDOC ## pub fn get_mut(&mut self) -> &mut S ### Description Gets a mutable reference to the underlying service. ### Returns - &mut S - A mutable reference to the wrapped service. ``` -------------------------------- ### Create New Compression Service Source: https://docs.rs/tower-http/latest/tower_http/compression/struct.Compression.html Creates a new Compression middleware wrapping the provided service. This is the entry point for using the compression functionality. ```rust pub fn new(service: S) -> Compression ``` -------------------------------- ### MapResponseBody::get_mut Source: https://docs.rs/tower-http/latest/tower_http/map_response_body/struct.MapResponseBody.html Gets a mutable reference to the underlying service. ```APIDOC ## `MapResponseBody::get_mut` ### Description Gets a mutable reference to the underlying service. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ### Returns A mutable reference to the wrapped service. ``` -------------------------------- ### MapResponseBody::get_ref Source: https://docs.rs/tower-http/latest/tower_http/map_response_body/struct.MapResponseBody.html Gets an immutable reference to the underlying service. ```APIDOC ## `MapResponseBody::get_ref` ### Description Gets a reference to the underlying service. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ### Returns An immutable reference to the wrapped service. ``` -------------------------------- ### MapRequestBody::get_mut Source: https://docs.rs/tower-http/latest/tower_http/map_request_body/struct.MapRequestBody.html Gets a mutable reference to the underlying service. ```APIDOC ## fn get_mut(&mut self) -> &mut S ### Description Gets a mutable reference to the underlying service. ``` -------------------------------- ### RequestDecompression::get_mut Source: https://docs.rs/tower-http/latest/tower_http/decompression/struct.RequestDecompression.html Gets a mutable reference to the underlying service. ```APIDOC ## RequestDecompression::get_mut ### Description Gets a mutable reference to the underlying service. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ``` -------------------------------- ### ready_oneshot Source: https://docs.rs/tower-http/latest/tower_http/auth/struct.AddAuthorization.html Yields the service when it is ready to accept a request. ```APIDOC ## fn ready_oneshot(self) -> ReadyOneshot ### Description Yields the service when it is ready to accept a request. ### Parameters - `self`: The service to wait for. ``` -------------------------------- ### Combine Policies with AND using PolicyExt Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/policy/trait.PolicyExt.html Use the `and` method to create a new policy that requires both the original and the provided policy to return `Action::Follow`. The `clone_body` method of the returned policy attempts to clone the body with both policies. ```rust use bytes::Bytes; use http_body_util::Full; use tower_http::follow_redirect::policy::{self, clone_body_fn, Limited, PolicyExt}; enum MyBody { Bytes(Bytes), Full(Full), } let policy = Limited::default().and::<_, _, ()>(clone_body_fn(|body| { if let MyBody::Bytes(buf) = body { Some(MyBody::Bytes(buf.clone())) } else { None } })); ``` -------------------------------- ### AddAuthorization::get_mut Source: https://docs.rs/tower-http/latest/tower_http/auth/add_authorization/struct.AddAuthorization.html Gets a mutable reference to the underlying service. ```APIDOC ## AddAuthorization::get_mut ### Description Gets a mutable reference to the underlying service. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ``` -------------------------------- ### AsyncRequireAuthorization::get_mut Source: https://docs.rs/tower-http/latest/tower_http/auth/async_require_authorization/struct.AsyncRequireAuthorization.html Gets a mutable reference to the underlying service. ```APIDOC ## AsyncRequireAuthorization::get_mut ### Description Gets a mutable reference to the inner service wrapped by the middleware. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ### Returns A mutable reference to the inner service. ``` -------------------------------- ### InFlightRequests::get_ref Source: https://docs.rs/tower-http/latest/tower_http/metrics/in_flight_requests/struct.InFlightRequests.html Gets a reference to the underlying service wrapped by `InFlightRequests`. ```APIDOC ## InFlightRequests::get_ref ### Description Gets a reference to the underlying service. ### Signature ```rust pub fn get_ref(&self) -> &S ``` ### Returns A reference to the inner service. ``` -------------------------------- ### Create a new CompressionLayer Source: https://docs.rs/tower-http/latest/tower_http/compression/struct.CompressionLayer.html Instantiates a new `CompressionLayer` with default settings. This layer can be used to add response body compression to a service. ```rust CompressionLayer::new() ``` -------------------------------- ### PolicyExt::and Method Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/policy/struct.And.html Creates a new Policy that returns Action::Follow only if both self and other policies return Action::Follow. Requires the `follow-redirect` feature. ```rust fn and(self, other: P) -> And where T: Policy, P: Policy, Available on **crate feature`follow-redirect`** only. Create a new `Policy` that returns `Action::Follow` only if `self` and `other` return `Action::Follow`. Read more ``` -------------------------------- ### RequestBodyTimeout::get_mut Source: https://docs.rs/tower-http/latest/tower_http/timeout/struct.RequestBodyTimeout.html Gets a mutable reference to the underlying service wrapped by `RequestBodyTimeout`. ```APIDOC ## RequestBodyTimeout::get_mut ### Description Gets a mutable reference to the underlying service. ### Method `pub fn get_mut(&mut self) -> &mut S` ``` -------------------------------- ### RequestBodyTimeout::get_ref Source: https://docs.rs/tower-http/latest/tower_http/timeout/struct.RequestBodyTimeout.html Gets an immutable reference to the underlying service wrapped by `RequestBodyTimeout`. ```APIDOC ## RequestBodyTimeout::get_ref ### Description Gets a reference to the underlying service. ### Method `pub fn get_ref(&self) -> &S` ``` -------------------------------- ### Enable Precompressed Zstd Serving Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Configures ServeFile to look for a precompressed zstd version of the file. If the client supports zstd encoding and the `.zst` file exists, it will be served instead of the original file. ```rust pub fn precompressed_zstd(self) -> Self ``` -------------------------------- ### ServeFile::precompressed_br Source: https://docs.rs/tower-http/latest/tower_http/services/fs/struct.ServeFile.html Enables serving of precompressed Brotli files if available and supported by the client. ```APIDOC ## ServeFile::precompressed_br ### Description Informs the service that it should also look for a precompressed brotli version of the file. If the client has an `Accept-Encoding` header that allows the brotli encoding, the file `foo.txt.br` will be served instead of `foo.txt`. If the precompressed file is not available, or the client doesn’t support it, the uncompressed version will be served instead. Both the precompressed version and the uncompressed version are expected to be present in the same directory. Different precompressed variants can be combined. ### Signature ```rust pub fn precompressed_br(self) -> Self ``` ``` -------------------------------- ### InFlightRequests::get_mut Source: https://docs.rs/tower-http/latest/tower_http/metrics/in_flight_requests/struct.InFlightRequests.html Gets a mutable reference to the underlying service wrapped by `InFlightRequests`. ```APIDOC ## InFlightRequests::get_mut ### Description Gets a mutable reference to the underlying service. ### Signature ```rust pub fn get_mut(&mut self) -> &mut S ``` ### Returns A mutable reference to the inner service. ``` -------------------------------- ### CatchPanic::get_mut Source: https://docs.rs/tower-http/latest/tower_http/catch_panic/struct.CatchPanic.html Gets a mutable reference to the underlying service wrapped by CatchPanic. ```APIDOC ## pub fn get_mut(&mut self) -> &mut S ### Description Gets a mutable reference to the underlying service. ### Returns - &mut S: A mutable reference to the inner service. ``` -------------------------------- ### DefaultMakeSpan::new Source: https://docs.rs/tower-http/latest/tower_http/trace/struct.DefaultMakeSpan.html Creates a new instance of DefaultMakeSpan. ```APIDOC ## DefaultMakeSpan::new ### Description Creates a new `DefaultMakeSpan`. ### Method `DefaultMakeSpan::new()` ### Returns A new `DefaultMakeSpan` instance. ``` -------------------------------- ### CatchPanic::get_ref Source: https://docs.rs/tower-http/latest/tower_http/catch_panic/struct.CatchPanic.html Gets an immutable reference to the underlying service wrapped by CatchPanic. ```APIDOC ## pub fn get_ref(&self) -> &S ### Description Gets a reference to the underlying service. ### Returns - &S: An immutable reference to the inner service. ``` -------------------------------- ### Policy Implementation for And Source: https://docs.rs/tower-http/latest/tower_http/follow_redirect/policy/struct.And.html Defines how the And struct behaves as a Policy, including its redirect, on_request, and clone_body methods. ```APIDOC ### impl Policy for And where A: Policy, B: Policy: #### fn redirect(&mut self, attempt: &Attempt<'_>) -> Result Invoked when the service received a response with a redirection status code (`3xx`). #### fn on_request(&mut self, request: &mut Request) Invoked right before the service makes a request, regardless of whether it is redirected or not. #### fn clone_body(&self, body: &Bd) -> Option Try to clone a request body before the service makes a redirected request. ``` -------------------------------- ### ServeDir::new Source: https://docs.rs/tower-http/latest/tower_http/services/struct.ServeDir.html Creates a new ServeDir service that will serve files from the specified directory. ```APIDOC ## ServeDir::new ### Description Creates a new `ServeDir` service that will serve files from the specified directory. ### Method ```rust pub fn new

(path: P) -> Self where P: AsRef, ``` ### Parameters * `path`: The directory path to serve files from. ``` -------------------------------- ### ServiceExt::ready_oneshot Source: https://docs.rs/tower-http/latest/tower_http/services/struct.ServeFile.html Yields the service when it is ready to accept a request. ```APIDOC ## ServiceExt::ready_oneshot ### Description Yields the service when it is ready to accept a request. ### Method Signature `fn ready_oneshot(self) -> ReadyOneshot` ### Type Parameters - `Request`: The type of the request the service accepts. ```