Expand description
Middleware for following redirections.
§Overview
The FollowRedirect
middleware retries requests with the inner Service
to follow HTTP
redirections.
The middleware tries to clone the original Request
when making a redirected request.
However, since 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
, 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
.
§Examples
§Basic usage
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use rama_http::{Body, Request, Response, StatusCode, header};
use rama_http::layer::follow_redirect::{FollowRedirectLayer, RequestUri};
let mut client = FollowRedirectLayer::new().layer(http_client);
let request = Request::builder()
.uri("https://rust-lang.org/")
.body(Body::empty())
.unwrap();
let response = client.serve(Context::default(), request).await?;
// Get the final request URI.
assert_eq!(response.extensions().get::<RequestUri>().unwrap().0, "https://www.rust-lang.org/");
§Customizing the Policy
You can use a Policy
value to customize how the middleware handles redirections.
use rama_core::service::service_fn;
use rama_core::layer::MapErrLayer;
use rama_core::{Context, Service, Layer};
use rama_http::{Body, Request, Response};
use rama_http::layer::follow_redirect::{
policy::{self, PolicyExt},
FollowRedirectLayer,
};
use rama_core::error::OpaqueError;
#[derive(Debug)]
enum MyError {
TooManyRedirects,
Other(OpaqueError),
}
impl MyError {
fn from_std(err: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Other(OpaqueError::from_std(err))
}
}
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 client = (
FollowRedirectLayer::with_policy(policy),
MapErrLayer::new(MyError::from_std),
).layer(http_client);
// ...
let _ = client.serve(Context::default(), Request::default()).await?;
Modules§
- Tools for customizing the behavior of a
FollowRedirect
middleware.
Structs§
- Middleware that retries requests with a
Service
to follow redirection responses. - Response
Extensions
value that represents the effective request URI of a response returned by aFollowRedirect
middleware.