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