1use std::cell::{Ref, RefMut};
2use std::{fmt, net};
3
4use http::{header, Method, Uri, Version};
5
6use crate::extensions::Extensions;
7use crate::header::HeaderMap;
8use crate::httpmessage::HttpMessage;
9use crate::message::{Message, RequestHead};
10use crate::payload::{Payload, PayloadStream};
11
12pub struct Request<P = PayloadStream> {
14 pub(crate) payload: Payload<P>,
15 pub(crate) head: Message<RequestHead>,
16}
17
18impl<P> HttpMessage for Request<P> {
19 type Stream = P;
20
21 #[inline]
22 fn headers(&self) -> &HeaderMap {
23 &self.head().headers
24 }
25
26 #[inline]
28 fn extensions(&self) -> Ref<'_, Extensions> {
29 self.head.extensions()
30 }
31
32 #[inline]
34 fn extensions_mut(&self) -> RefMut<'_, Extensions> {
35 self.head.extensions_mut()
36 }
37
38 fn take_payload(&mut self) -> Payload<P> {
39 std::mem::replace(&mut self.payload, Payload::None)
40 }
41}
42
43impl From<Message<RequestHead>> for Request<PayloadStream> {
44 fn from(head: Message<RequestHead>) -> Self {
45 Request {
46 head,
47 payload: Payload::None,
48 }
49 }
50}
51
52impl Request<PayloadStream> {
53 pub fn new() -> Request<PayloadStream> {
55 Request {
56 head: Message::new(),
57 payload: Payload::None,
58 }
59 }
60}
61
62impl<P> Request<P> {
63 pub fn with_payload(payload: Payload<P>) -> Request<P> {
65 Request {
66 payload,
67 head: Message::new(),
68 }
69 }
70
71 pub fn replace_payload<P1>(self, payload: Payload<P1>) -> (Request<P1>, Payload<P>) {
73 let pl = self.payload;
74 (
75 Request {
76 payload,
77 head: self.head,
78 },
79 pl,
80 )
81 }
82
83 pub fn payload(&mut self) -> &mut Payload<P> {
85 &mut self.payload
86 }
87
88 pub fn take_payload(&mut self) -> Payload<P> {
90 std::mem::replace(&mut self.payload, Payload::None)
91 }
92
93 pub fn into_parts(self) -> (Message<RequestHead>, Payload<P>) {
95 (self.head, self.payload)
96 }
97
98 #[inline]
99 pub fn head(&self) -> &RequestHead {
101 &*self.head
102 }
103
104 #[inline]
105 #[doc(hidden)]
106 pub fn head_mut(&mut self) -> &mut RequestHead {
108 &mut *self.head
109 }
110
111 pub fn headers_mut(&mut self) -> &mut HeaderMap {
113 &mut self.head_mut().headers
114 }
115
116 #[inline]
118 pub fn uri(&self) -> &Uri {
119 &self.head().uri
120 }
121
122 #[inline]
124 pub fn uri_mut(&mut self) -> &mut Uri {
125 &mut self.head_mut().uri
126 }
127
128 #[inline]
130 pub fn method(&self) -> &Method {
131 &self.head().method
132 }
133
134 #[inline]
136 pub fn version(&self) -> Version {
137 self.head().version
138 }
139
140 #[inline]
142 pub fn path(&self) -> &str {
143 self.head().uri.path()
144 }
145
146 #[inline]
148 pub fn upgrade(&self) -> bool {
149 if let Some(conn) = self.head().headers.get(header::CONNECTION) {
150 if let Ok(s) = conn.to_str() {
151 return s.to_lowercase().contains("upgrade");
152 }
153 }
154 self.head().method == Method::CONNECT
155 }
156
157 #[inline]
162 pub fn peer_addr(&self) -> Option<net::SocketAddr> {
163 self.head().peer_addr
164 }
165}
166
167impl<P> fmt::Debug for Request<P> {
168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169 writeln!(
170 f,
171 "\nRequest {:?} {}:{}",
172 self.version(),
173 self.method(),
174 self.path()
175 )?;
176 if let Some(q) = self.uri().query().as_ref() {
177 writeln!(f, " query: ?{:?}", q)?;
178 }
179 writeln!(f, " headers:")?;
180 for (key, val) in self.headers() {
181 writeln!(f, " {:?}: {:?}", key, val)?;
182 }
183 Ok(())
184 }
185}
186
187#[cfg(test)]
188mod tests {
189 use super::*;
190 use std::convert::TryFrom;
191
192 #[test]
193 fn test_basics() {
194 let msg = Message::new();
195 let mut req = Request::from(msg);
196 req.headers_mut().insert(
197 header::CONTENT_TYPE,
198 header::HeaderValue::from_static("text/plain"),
199 );
200 assert!(req.headers().contains_key(header::CONTENT_TYPE));
201
202 *req.uri_mut() = Uri::try_from("/index.html?q=1").unwrap();
203 assert_eq!(req.uri().path(), "/index.html");
204 assert_eq!(req.uri().query(), Some("q=1"));
205
206 let s = format!("{:?}", req);
207 assert!(s.contains("Request HTTP/1.1 GET:/index.html"));
208 }
209}