tosic_http/request/
mod.rs

1//! The request object contains information about the incoming request
2
3mod test;
4
5use crate::body::message_body::MessageBody;
6use crate::body::BoxBody;
7use crate::error::ServerError;
8use crate::futures::{ok, Ready};
9use crate::state::State;
10use crate::traits::from_request::FromRequest;
11use bytes::Bytes;
12use http::{HeaderMap, HeaderValue, Method, Uri, Version};
13use httparse::{Request, Status};
14use std::collections::BTreeMap;
15use std::convert::Infallible;
16use std::ops::{Deref, DerefMut};
17use std::str::FromStr;
18
19#[derive(Clone, Debug, Default)]
20#[allow(missing_docs)]
21/// The request object
22pub struct HttpRequest {
23    pub method: Method,
24    pub uri: Uri,
25    pub headers: HeaderMap,
26    pub version: Version,
27    pub params: BTreeMap<String, String>,
28    pub data: State,
29}
30
31#[derive(Clone, Debug)]
32/// The payload of the request
33pub struct HttpPayload(BoxBody);
34
35impl Default for HttpPayload {
36    fn default() -> Self {
37        HttpPayload::new(BoxBody::new(()))
38    }
39}
40
41impl HttpPayload {
42    /// Create a new `HttpPayload`
43    pub(crate) fn new(body: BoxBody) -> Self {
44        HttpPayload(body)
45    }
46
47    /// Create a new `HttpPayload` from bytes
48    pub(crate) fn from_bytes(bytes: Bytes) -> Self {
49        HttpPayload(BoxBody::new(bytes))
50    }
51}
52
53impl Deref for HttpPayload {
54    type Target = BoxBody;
55
56    fn deref(&self) -> &Self::Target {
57        &self.0
58    }
59}
60
61impl DerefMut for HttpPayload {
62    fn deref_mut(&mut self) -> &mut Self::Target {
63        &mut self.0
64    }
65}
66
67impl HttpRequest {
68    /// Create a new `HttpRequest`
69    pub(crate) fn from_bytes(buffer: &[u8]) -> Result<(Self, HttpPayload), ServerError> {
70        let mut headers = [httparse::EMPTY_HEADER; 32];
71        let mut req = Request::new(&mut headers);
72
73        match req.parse(buffer) {
74            Ok(Status::Complete(_)) => {
75                let parsed_req: Self = req.into();
76
77                // Extract body
78                let headers_end = buffer
79                    .windows(4)
80                    .position(|window| window == b"\r\n\r\n")
81                    .map(|pos| pos + 4)
82                    .unwrap_or(buffer.len());
83                let body = buffer[headers_end..].to_vec();
84
85                Ok((
86                    parsed_req,
87                    HttpPayload::from_bytes(body.try_into_bytes().unwrap()),
88                ))
89            }
90            Ok(Status::Partial) => Err(ServerError::PartialParsed),
91            Err(e) => Err(ServerError::ParseError(e)),
92        }
93    }
94
95    /// Get the uri
96    pub fn uri(&self) -> &Uri {
97        &self.uri
98    }
99
100    /// Get the path
101    pub fn path(&self) -> &str {
102        self.uri().path()
103    }
104
105    /// Get the query
106    pub fn query(&self) -> Option<&str> {
107        self.uri().query()
108    }
109
110    /// Get the method
111    pub fn method(&self) -> &Method {
112        &self.method
113    }
114
115    /// Get the headers
116    pub fn headers(&self) -> &HeaderMap {
117        &self.headers
118    }
119
120    /// Get the version
121    pub fn version(&self) -> &Version {
122        &self.version
123    }
124
125    /// Get the params
126    pub fn params(&self) -> &BTreeMap<String, String> {
127        &self.params
128    }
129
130    /// Get the params
131    pub fn params_mut(&mut self) -> &mut BTreeMap<String, String> {
132        &mut self.params
133    }
134}
135
136impl FromRequest for HttpRequest {
137    type Error = Infallible;
138    type Future = Ready<Result<Self, Self::Error>>;
139
140    fn from_request(req: &HttpRequest, _: &mut HttpPayload) -> Self::Future {
141        ok(req.clone())
142    }
143}
144
145impl From<Request<'_, '_>> for HttpRequest {
146    fn from(value: Request) -> Self {
147        let version = match value.version.unwrap_or(0) {
148            0 => Version::HTTP_10,
149            1 => Version::HTTP_11,
150            _ => Version::HTTP_11,
151        };
152        let method: Method = value.method.unwrap_or("GET").parse().unwrap_or_default();
153        let uri = Uri::from_str(value.path.unwrap_or_default()).unwrap_or_default();
154        let mut headers = HeaderMap::new();
155
156        for header in value.headers {
157            // Parse header name into an owned HeaderName
158            let header_name = header.name.parse::<http::header::HeaderName>().unwrap();
159
160            // Create HeaderValue from bytes (this clones the data)
161            let header_value = HeaderValue::from_bytes(header.value).unwrap();
162
163            headers.append(header_name, header_value);
164        }
165
166        Self {
167            method,
168            uri,
169            headers,
170            version,
171            ..Default::default()
172        }
173    }
174}