1use std::{cell::Ref, cell::RefMut, fmt, mem, net};
2
3use crate::http::header::{self, HeaderMap};
4use crate::http::httpmessage::HttpMessage;
5use crate::http::message::{Message, RequestHead};
6use crate::http::{Method, Uri, Version, payload::Payload};
7use crate::{io::IoRef, io::types, util::Extensions};
8
9pub struct Request {
11 pub(crate) payload: Payload,
12 pub(crate) head: Message<RequestHead>,
13}
14
15impl HttpMessage for Request {
16 #[inline]
17 fn message_headers(&self) -> &HeaderMap {
18 &self.head().headers
19 }
20
21 #[inline]
23 fn message_extensions(&self) -> Ref<'_, Extensions> {
24 self.head.extensions()
25 }
26
27 #[inline]
29 fn message_extensions_mut(&self) -> RefMut<'_, Extensions> {
30 self.head.extensions_mut()
31 }
32}
33
34impl From<Message<RequestHead>> for Request {
35 fn from(head: Message<RequestHead>) -> Self {
36 Request {
37 head,
38 payload: Payload::None,
39 }
40 }
41}
42
43impl Request {
44 pub fn new() -> Request {
46 Request {
47 head: Message::new(),
48 payload: Payload::None,
49 }
50 }
51}
52
53impl Request {
54 pub fn with_payload(payload: Payload) -> Request {
56 Request {
57 payload,
58 head: Message::new(),
59 }
60 }
61
62 #[inline]
63 pub fn head(&self) -> &RequestHead {
65 &self.head
66 }
67
68 #[inline]
69 #[doc(hidden)]
70 pub fn head_mut(&mut self) -> &mut RequestHead {
72 &mut self.head
73 }
74
75 #[inline]
77 pub fn uri(&self) -> &Uri {
78 &self.head().uri
79 }
80
81 #[inline]
83 pub fn uri_mut(&mut self) -> &mut Uri {
84 &mut self.head_mut().uri
85 }
86
87 #[inline]
89 pub fn method(&self) -> &Method {
90 &self.head().method
91 }
92
93 #[inline]
95 pub fn version(&self) -> Version {
96 self.head().version
97 }
98
99 #[inline]
101 pub fn path(&self) -> &str {
102 self.head().uri.path()
103 }
104
105 #[inline]
106 pub fn headers(&self) -> &HeaderMap {
108 &self.head().headers
109 }
110
111 pub fn headers_mut(&mut self) -> &mut HeaderMap {
113 &mut self.head_mut().headers
114 }
115
116 #[inline]
118 pub fn upgrade(&self) -> bool {
119 self.head().upgrade() || self.head().method == Method::CONNECT
120 }
121
122 #[inline]
124 pub fn io(&self) -> Option<&IoRef> {
125 self.head().io.as_ref()
126 }
127
128 #[inline]
133 pub fn peer_addr(&self) -> Option<net::SocketAddr> {
134 self.head().io.as_ref().and_then(|io| {
135 io.query::<types::PeerAddr>()
136 .get()
137 .map(types::PeerAddr::into_inner)
138 })
139 }
140
141 pub fn payload(&mut self) -> &mut Payload {
143 &mut self.payload
144 }
145
146 pub fn take_payload(&mut self) -> Payload {
148 mem::take(&mut self.payload)
149 }
150
151 pub fn replace_payload(&mut self, payload: Payload) -> Payload {
153 mem::replace(&mut self.payload, payload)
154 }
155
156 #[inline]
158 pub fn extensions(&self) -> Ref<'_, Extensions> {
159 self.head.extensions()
160 }
161
162 #[inline]
164 pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
165 self.head.extensions_mut()
166 }
167
168 pub(crate) fn into_parts(self) -> (Message<RequestHead>, Payload) {
170 (self.head, self.payload)
171 }
172}
173
174impl Default for Request {
175 fn default() -> Request {
176 Request::new()
177 }
178}
179
180impl fmt::Debug for Request {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 writeln!(
183 f,
184 "\nRequest {:?} {}:{}",
185 self.version(),
186 self.method(),
187 self.path()
188 )?;
189 if let Some(q) = self.uri().query().as_ref() {
190 writeln!(f, " query: ?{q:?}")?;
191 }
192 writeln!(f, " headers:")?;
193 for (key, val) in self.headers() {
194 if key == header::AUTHORIZATION {
195 writeln!(f, " {key:?}: <REDACTED>")?;
196 } else {
197 writeln!(f, " {key:?}: {val:?}")?;
198 }
199 }
200 Ok(())
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207
208 #[test]
209 fn test_basics() {
210 let msg = Message::new();
211 let req = Request::new();
212 assert!(req.io().is_none());
213 let mut req = Request::from(msg);
214 assert!(req.io().is_none());
215
216 req.headers_mut().insert(
217 header::CONTENT_TYPE,
218 header::HeaderValue::from_static("text/plain"),
219 );
220 assert!(req.headers().contains_key(header::CONTENT_TYPE));
221
222 req.extensions_mut()
223 .insert(header::HeaderValue::from_static("text/plain"));
224 assert_eq!(
225 req.extensions().get::<header::HeaderValue>().unwrap(),
226 header::HeaderValue::from_static("text/plain")
227 );
228
229 req.head_mut().headers_mut().insert(
230 header::CONTENT_LENGTH,
231 header::HeaderValue::from_static("100"),
232 );
233 assert!(req.headers().contains_key(header::CONTENT_LENGTH));
234
235 req.head_mut().no_chunking(true);
236 assert!(!req.head().chunked());
237 req.head_mut().no_chunking(false);
238 assert!(req.head().chunked());
239
240 *req.uri_mut() = Uri::try_from("/index.html?q=1").unwrap();
241 assert_eq!(req.uri().path(), "/index.html");
242 assert_eq!(req.uri().query(), Some("q=1"));
243
244 let s = format!("{req:?}");
245 assert!(s.contains("Request HTTP/1.1 GET:/index.html"));
246
247 let s = format!("{:?}", req.head());
248 assert!(s.contains("RequestHead { id: 0, uri:"));
249 }
250}