• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::{rejection::*, FromRequest, FromRequestParts};
2 use crate::{BoxError, RequestExt};
3 use async_trait::async_trait;
4 use bytes::Bytes;
5 use http::{request::Parts, HeaderMap, Method, Request, Uri, Version};
6 use std::convert::Infallible;
7 
8 #[async_trait]
9 impl<S, B> FromRequest<S, B> for Request<B>
10 where
11     B: Send,
12     S: Send + Sync,
13 {
14     type Rejection = Infallible;
15 
from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection>16     async fn from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection> {
17         Ok(req)
18     }
19 }
20 
21 #[async_trait]
22 impl<S> FromRequestParts<S> for Method
23 where
24     S: Send + Sync,
25 {
26     type Rejection = Infallible;
27 
from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection>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]
34 impl<S> FromRequestParts<S> for Uri
35 where
36     S: Send + Sync,
37 {
38     type Rejection = Infallible;
39 
from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection>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]
46 impl<S> FromRequestParts<S> for Version
47 where
48     S: Send + Sync,
49 {
50     type Rejection = Infallible;
51 
from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection>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/latest/axum/extract/struct.TypedHeader.html
62 #[async_trait]
63 impl<S> FromRequestParts<S> for HeaderMap
64 where
65     S: Send + Sync,
66 {
67     type Rejection = Infallible;
68 
from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection>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]
75 impl<S, B> FromRequest<S, B> for Bytes
76 where
77     B: http_body::Body + Send + 'static,
78     B::Data: Send,
79     B::Error: Into<BoxError>,
80     S: Send + Sync,
81 {
82     type Rejection = BytesRejection;
83 
from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection>84     async fn from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection> {
85         let bytes = match req.into_limited_body() {
86             Ok(limited_body) => crate::body::to_bytes(limited_body)
87                 .await
88                 .map_err(FailedToBufferBody::from_err)?,
89             Err(unlimited_body) => crate::body::to_bytes(unlimited_body)
90                 .await
91                 .map_err(FailedToBufferBody::from_err)?,
92         };
93 
94         Ok(bytes)
95     }
96 }
97 
98 #[async_trait]
99 impl<S, B> FromRequest<S, B> for String
100 where
101     B: http_body::Body + Send + 'static,
102     B::Data: Send,
103     B::Error: Into<BoxError>,
104     S: Send + Sync,
105 {
106     type Rejection = StringRejection;
107 
from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection>108     async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
109         let bytes = Bytes::from_request(req, state)
110             .await
111             .map_err(|err| match err {
112                 BytesRejection::FailedToBufferBody(inner) => {
113                     StringRejection::FailedToBufferBody(inner)
114                 }
115             })?;
116 
117         let string = std::str::from_utf8(&bytes)
118             .map_err(InvalidUtf8::from_err)?
119             .to_owned();
120 
121         Ok(string)
122     }
123 }
124 
125 #[async_trait]
126 impl<S, B> FromRequest<S, B> for Parts
127 where
128     B: Send + 'static,
129     S: Send + Sync,
130 {
131     type Rejection = Infallible;
132 
from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection>133     async fn from_request(req: Request<B>, _: &S) -> Result<Self, Self::Rejection> {
134         Ok(req.into_parts().0)
135     }
136 }
137