Skip to main content

Module tower

Module tower 

Source
Available on crate feature tower only.
Expand description

The rules as tower layers, so they stack in front of any service.

Origins::accept and unsupported are the decisions; this module is them wired as middleware, which is how a shell actually wants to apply them. The inner service can be anything: a topcoat router, an axum router, a ServeDir. None of it knows it is behind a webview.

let service = ServiceBuilder::new()
    .layer(CanonicalOriginLayer::new(origins.clone()))
    .layer(follow_redirects())
    .layer(RefuseUnsupportedLayer::new())
    .service(your_router);

§Order

Outermost first, and it matters. The origin rewrite runs before anything else, because every layer under it gets to assume one canonical origin.

An ordinary CSRF check compares Origin against Host, and some refuse a scheme that is not http or https outright. Either way the two headers have to move together, or the application’s own form post is refused. That is what makes the rewrite the outermost layer, and a_csrf_check_needs_the_rewrite_underneath_it holds it there.

RefuseUnsupportedLayer goes under the redirect follower. Over it, the check only ever sees the response that survives the last hop, and a Set-Cookie on a hop that itself redirects is exactly how a login answers a POST. Following past it drops the cookie with nothing left to read anywhere. Under it, every hop is checked before anything is followed.

§Why are redirects not in here?

Because tower-http already does it. Its FollowRedirect re-enters the inner service, and its SameOrigin policy refuses a Location off our own origin - without it, the shell would fetch from the internet on the application’s say-so. Limited caps the hop count. Both are re-exported, so you need no direct dependency on it.

Writing it here would have meant a partial reimplementation of the Fetch standard. The tests in this module pin the behaviour we lean on, so an upgrade that changes it fails here instead of in your application.

Modules§

follow_redirect
Middleware for following redirections.

Structs§

CanonicalOrigin
The service CanonicalOriginLayer produces.
CanonicalOriginLayer
Rewrites every request into the canonical origin, and refuses the ones that name somebody else’s.
FollowRedirect
Middleware that retries requests with a Service to follow redirection responses.
FollowRedirectLayer
Layer for retrying requests with a Service to follow redirection responses.
RefuseUnsupported
The service RefuseUnsupportedLayer produces.
RefuseUnsupportedLayer
Replaces a response this transport cannot carry with one that says so.

Constants§

MAX_REDIRECTS
How many redirects to follow before delivering the last one unfollowed.

Functions§

follow_redirects
The redirect follower this transport needs, policy and all.