axum_core/extract/
request_parts.rs

1use super::{rejection::*, FromRequest, FromRequestParts, Request};
2use crate::{body::Body, RequestExt};
3use async_trait::async_trait;
4use bytes::{BufMut, Bytes, BytesMut};
5use http::{request::Parts, Extensions, HeaderMap, Method, Uri, Version};
6use http_body_util::BodyExt;
7use std::convert::Infallible;
8
9#[async_trait]
10impl<S> FromRequest<S> for Request
11where
12    S: Send + Sync,
13{
14    type Rejection = Infallible;
15
16    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
17        Ok(req)
18    }
19}
20
21#[async_trait]
22impl<S> FromRequestParts<S> for Method
23where
24    S: Send + Sync,
25{
26    type Rejection = Infallible;
27
28    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
29        Ok(parts.method.clone())
30    }
31}
32
33#[async_trait]
34impl<S> FromRequestParts<S> for Uri
35where
36    S: Send + Sync,
37{
38    type Rejection = Infallible;
39
40    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
41        Ok(parts.uri.clone())
42    }
43}
44
45#[async_trait]
46impl<S> FromRequestParts<S> for Version
47where
48    S: Send + Sync,
49{
50    type Rejection = Infallible;
51
52    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
53        Ok(parts.version)
54    }
55}
56
57/// Clone the headers from the request.
58///
59/// Prefer using [`TypedHeader`] to extract only the headers you need.
60///
61/// [`TypedHeader`]: https://docs.rs/axum/0.7/axum/extract/struct.TypedHeader.html
62#[async_trait]
63impl<S> FromRequestParts<S> for HeaderMap
64where
65    S: Send + Sync,
66{
67    type Rejection = Infallible;
68
69    async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
70        Ok(parts.headers.clone())
71    }
72}
73
74#[async_trait]
75impl<S> FromRequest<S> for BytesMut
76where
77    S: Send + Sync,
78{
79    type Rejection = BytesRejection;
80
81    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
82        let mut body = req.into_limited_body();
83        let mut bytes = BytesMut::new();
84        body_to_bytes_mut(&mut body, &mut bytes).await?;
85        Ok(bytes)
86    }
87}
88
89async fn body_to_bytes_mut(body: &mut Body, bytes: &mut BytesMut) -> Result<(), BytesRejection> {
90    while let Some(frame) = body
91        .frame()
92        .await
93        .transpose()
94        .map_err(FailedToBufferBody::from_err)?
95    {
96        let Ok(data) = frame.into_data() else {
97            return Ok(());
98        };
99        bytes.put(data);
100    }
101
102    Ok(())
103}
104
105#[async_trait]
106impl<S> FromRequest<S> for Bytes
107where
108    S: Send + Sync,
109{
110    type Rejection = BytesRejection;
111
112    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
113        let bytes = req
114            .into_limited_body()
115            .collect()
116            .await
117            .map_err(FailedToBufferBody::from_err)?
118            .to_bytes();
119
120        Ok(bytes)
121    }
122}
123
124#[async_trait]
125impl<S> FromRequest<S> for String
126where
127    S: Send + Sync,
128{
129    type Rejection = StringRejection;
130
131    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
132        let bytes = Bytes::from_request(req, state)
133            .await
134            .map_err(|err| match err {
135                BytesRejection::FailedToBufferBody(inner) => {
136                    StringRejection::FailedToBufferBody(inner)
137                }
138            })?;
139
140        let string = String::from_utf8(bytes.into()).map_err(InvalidUtf8::from_err)?;
141
142        Ok(string)
143    }
144}
145
146#[async_trait]
147impl<S> FromRequestParts<S> for Parts
148where
149    S: Send + Sync,
150{
151    type Rejection = Infallible;
152
153    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
154        Ok(parts.clone())
155    }
156}
157
158#[async_trait]
159impl<S> FromRequestParts<S> for Extensions
160where
161    S: Send + Sync,
162{
163    type Rejection = Infallible;
164
165    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
166        Ok(parts.extensions.clone())
167    }
168}
169
170#[async_trait]
171impl<S> FromRequest<S> for Body
172where
173    S: Send + Sync,
174{
175    type Rejection = Infallible;
176
177    async fn from_request(req: Request, _: &S) -> Result<Self, Self::Rejection> {
178        Ok(req.into_body())
179    }
180}