Skip to main content

tower_http/csrf/
response.rs

1use http::{Response, StatusCode};
2
3use super::ProtectionError;
4
5/// Builds the response returned by [`Csrf`] when a request fails CSRF protection.
6///
7/// Implemented for any `FnMut(ProtectionError) -> Response<B> + Clone`, so a
8/// closure can be passed directly to
9/// [`CsrfLayer::with_rejection_response`](super::CsrfLayer::with_rejection_response).
10///
11/// [`Csrf`]: super::Csrf
12pub trait ResponseForProtectionError<B>: Clone {
13    /// Builds the response from the rejection error.
14    fn response_for_protection_error(&mut self, error: ProtectionError) -> Response<B>;
15}
16
17impl<F, B> ResponseForProtectionError<B> for F
18where
19    F: FnMut(ProtectionError) -> Response<B> + Clone,
20{
21    fn response_for_protection_error(&mut self, error: ProtectionError) -> Response<B> {
22        self(error)
23    }
24}
25
26/// Default [`ResponseForProtectionError`] used by
27/// [`CsrfLayer::new`](super::CsrfLayer::new).
28///
29/// Produces a `403 Forbidden` response with an empty body. The originating
30/// [`ProtectionError`] is attached to the response's extensions by [`Csrf`]
31/// itself, so it is present regardless of which builder produced the response.
32///
33/// [`Csrf`]: super::Csrf
34#[derive(Clone, Copy, Debug, Default)]
35#[non_exhaustive]
36pub struct DefaultResponseForProtectionError;
37
38impl<B: Default> ResponseForProtectionError<B> for DefaultResponseForProtectionError {
39    fn response_for_protection_error(&mut self, _error: ProtectionError) -> Response<B> {
40        let mut response = Response::new(B::default());
41        *response.status_mut() = StatusCode::FORBIDDEN;
42
43        response
44    }
45}