httpz/
request.rs

1use http::{request::Parts, HeaderMap, Method, Uri, Version};
2
3use crate::Server;
4
5/// Represent a HTTP request
6#[derive(Debug)]
7pub struct Request(pub(crate) Parts, pub(crate) Vec<u8>, pub(crate) Server);
8
9impl Request {
10    /// Create a new [Request] from a [http::Request] and a [httpz::Server].
11    pub fn new(req: http::Request<Vec<u8>>, server: Server) -> Self {
12        let (parts, body) = req.into_parts();
13        Self(parts, body, server)
14    }
15
16    /// Get the uri of the request.
17    pub fn uri(&self) -> &Uri {
18        &self.0.uri
19    }
20
21    /// Get the version of the request.
22    pub fn version(&self) -> Version {
23        self.0.version
24    }
25
26    /// Get the method of the request.
27    pub fn method(&self) -> &Method {
28        &self.0.method
29    }
30
31    /// Get the headers of the request.
32    pub fn headers(&self) -> &HeaderMap {
33        &self.0.headers
34    }
35
36    /// Get the headers of the request.
37    pub fn headers_mut(&mut self) -> &mut HeaderMap {
38        &mut self.0.headers
39    }
40
41    /// Get the body of the request.
42    pub fn body(&self) -> &Vec<u8> {
43        &self.1
44    }
45
46    /// Get a new [CookieJar] which is derived from the cookies in the request.
47    #[cfg(feature = "cookies")]
48    pub fn cookies(&self) -> cookie::CookieJar {
49        use {
50            cookie::{Cookie, CookieJar},
51            http::header::COOKIE,
52        };
53
54        let mut jar = CookieJar::new();
55        for cookie in self
56            .0
57            .headers
58            .get_all(COOKIE)
59            .into_iter()
60            .filter_map(|value| value.to_str().ok())
61            .flat_map(|value| value.split(';'))
62            .filter_map(|cookie| Cookie::parse_encoded(cookie.to_owned()).ok())
63        {
64            jar.add_original(cookie);
65        }
66
67        jar
68    }
69
70    /// query_pairs returns an iterator of the query parameters.
71    pub fn query_pairs(&self) -> Option<form_urlencoded::Parse<'_>> {
72        self.0
73            .uri
74            .query()
75            .map(|query| form_urlencoded::parse(query.as_bytes()))
76    }
77
78    /// split the [http::Parts]] and the body
79    pub fn into_parts(self) -> (Parts, Vec<u8>) {
80        (self.0, self.1)
81    }
82
83    /// get the [http::Parts] of the request
84    pub fn parts(&self) -> &Parts {
85        &self.0
86    }
87
88    /// get the [http::Parts] of the request
89    pub fn parts_mut(&mut self) -> &mut Parts {
90        &mut self.0
91    }
92
93    /// expose the inner [http::Request]
94    pub fn expose(self) -> http::Request<Vec<u8>> {
95        http::Request::from_parts(self.0, self.1)
96    }
97
98    /// Get the extensions of the request.
99    pub fn extensions(&self) -> &http::Extensions {
100        &self.0.extensions
101    }
102
103    /// Get the extensions of the request.
104    pub fn extensions_mut(&mut self) -> &mut http::Extensions {
105        &mut self.0.extensions
106    }
107
108    /// get the type of the server that handled this request
109    pub fn server(&self) -> Server {
110        self.2
111    }
112
113    // TODO: Remove usage of this from rspc and then here.
114    #[doc(hidden)]
115    pub fn _internal_dangerously_clone(&self) -> Self {
116        let mut parts = http::Request::<()>::default().into_parts().0;
117        parts.method = self.0.method.clone();
118        parts.uri = self.0.uri.clone();
119        parts.version = self.0.version;
120        parts.headers = self.0.headers.clone();
121        // parts.extensions = self.0.extensions().clone(); // TODO: Can't `Clone` extensions. Hence why this method is dangerous.
122
123        Self(parts, self.1.clone(), self.2)
124    }
125}