hyper_simple_server/
extensions.rs

1
2
3use crate::prelude::*;
4
5
6
7
8#[ cfg (feature = "hss-extensions") ]
9pub trait RequestExt <B>
10	where
11		B : BodyTrait,
12{
13	fn is_get (&self) -> bool;
14	fn is_head (&self) -> bool;
15	fn is_put (&self) -> bool;
16	fn is_post (&self) -> bool;
17	fn is_delete (&self) -> bool;
18	fn is_patch (&self) -> bool;
19	fn is_options (&self) -> bool;
20	
21	fn uri_path (&self) -> &str;
22	fn uri_query (&self) -> Option<&str>;
23	
24	fn header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue>;
25	fn header_all (&self, _name : impl AsHeaderName) -> http::header::GetAll<'_, HeaderValue>;
26	
27	fn header_str (&self, _name : impl AsHeaderName) -> Option<&str> {
28		self.header (_name) .and_then (|_value| _value.to_str () .ok ())
29	}
30	
31	fn header_host (&self) -> Option<&str> {
32		self.header_str (consts::HOST)
33	}
34}
35
36
37#[ cfg (feature = "hss-extensions") ]
38impl <B> RequestExt<B> for Request<B>
39	where
40		B : BodyTrait,
41{
42	fn is_get (&self) -> bool {
43		self.method () == Method::GET
44	}
45	fn is_head (&self) -> bool {
46		self.method () == Method::HEAD
47	}
48	fn is_put (&self) -> bool {
49		self.method () == Method::PUT
50	}
51	fn is_post (&self) -> bool {
52		self.method () == Method::POST
53	}
54	fn is_delete (&self) -> bool {
55		self.method () == Method::DELETE
56	}
57	fn is_patch (&self) -> bool {
58		self.method () == Method::PATCH
59	}
60	fn is_options (&self) -> bool {
61		self.method () == Method::OPTIONS
62	}
63	
64	fn uri_path (&self) -> &str {
65		self.uri () .path ()
66	}
67	
68	fn uri_query (&self) -> Option<&str> {
69		self.uri () .query ()
70	}
71	
72	fn header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue> {
73		self.headers () .get (_name)
74	}
75	
76	fn header_all (&self, _name : impl AsHeaderName) -> http::header::GetAll<'_, HeaderValue> {
77		self.headers () .get_all (_name)
78	}
79}
80
81
82
83
84#[ cfg (feature = "hss-extensions") ]
85pub trait ResponseExt <B>
86	where
87		B : BodyTrait,
88{
89	fn status (&self) -> StatusCode;
90	fn set_status (&mut self, _status : StatusCode) -> &mut Self;
91	
92	fn get_header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue>;
93	fn set_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self;
94	fn add_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self;
95	
96	fn set_body (&mut self, _body : impl Into<B>) -> &mut Self;
97	
98	fn set_status_200 (&mut self) -> &mut Self {
99		self.set_status (consts::OK)
100	}
101	
102	fn set_content_type (&mut self, _content_type : impl Into<HeaderValue>) -> &mut Self {
103		self.set_header (consts::CONTENT_TYPE, _content_type)
104	}
105	
106	fn set_header_str_static (&mut self, _name : impl IntoHeaderName, _value : &'static str) -> &mut Self {
107		self.set_header (_name, HeaderValue::from_static (_value))
108	}
109	
110	fn set_header_string (&mut self, _name : impl IntoHeaderName, _value : String) -> &mut Self {
111		self.set_header (_name, HeaderValue::try_from (_value) .or_panic (0x627a7cff))
112	}
113	
114	fn add_header_str_static (&mut self, _name : impl IntoHeaderName, _value : &'static str) -> &mut Self {
115		self.add_header (_name, HeaderValue::from_static (_value))
116	}
117	
118	fn add_header_string (&mut self, _name : impl IntoHeaderName, _value : String) -> &mut Self {
119		self.add_header (_name, HeaderValue::try_from (_value) .or_panic (0x1ac00c46))
120	}
121	
122	fn content_type (&self) -> Option<ContentType> {
123		if let Some (_content_type) = self.get_header (consts::CONTENT_TYPE) {
124			if let Ok (_content_type) = _content_type.to_str () {
125				ContentType::from_str (_content_type)
126			} else {
127				None
128			}
129		} else {
130			None
131		}
132	}
133	
134	fn content_type_or_unknown (&self) -> ContentType {
135		self.content_type () .unwrap_or (ContentType::Unknown)
136	}
137}
138
139
140#[ cfg (feature = "hss-extensions") ]
141impl <B> ResponseExt<B> for Response<B>
142	where
143		B : BodyTrait,
144{
145	fn status (&self) -> StatusCode {
146		self.status ()
147	}
148	
149	fn set_status (&mut self, _status : StatusCode) -> &mut Self {
150		*self.status_mut () = _status;
151		self
152	}
153	
154	fn get_header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue> {
155		self.headers () .get (_name)
156	}
157	
158	fn set_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self {
159		self.headers_mut () .insert (_name, _value.into ());
160		self
161	}
162	
163	fn add_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self {
164		self.headers_mut () .append (_name, _value.into ());
165		self
166	}
167	
168	fn set_body (&mut self, _body : impl Into<B>) -> &mut Self {
169		*self.body_mut () = _body.into ();
170		self
171	}
172}
173
174
175
176
177#[ cfg (feature = "hss-extensions") ]
178pub trait ResponseExtBuild <B>
179	where
180		B : BodyTrait,
181		Self : Sized,
182		Self : ResponseExt<B>,
183{
184	fn new_with_status_and_body (_status : StatusCode, _body : impl Into<B>, _content_type : Option<impl Into<HeaderValue>>) -> Self;
185	
186	fn new_empty () -> Self where B : Default {
187		let _content_type : Option<ContentType> = None;
188		Self::new_with_status_and_body (consts::OK, B::default (), _content_type)
189	}
190	
191	fn new_with_status (_status : StatusCode) -> Self where B : Default {
192		let _content_type : Option<ContentType> = None;
193		Self::new_with_status_and_body (_status, B::default (), _content_type)
194	}
195	
196	fn new_201 () -> Self where B : Default {
197		Self::new_with_status (consts::CREATED)
198	}
199	
200	fn new_200_with_body (_body : impl Into<B>, _content_type : Option<impl Into<HeaderValue>>) -> Self {
201		Self::new_with_status_and_body (consts::OK, _body, _content_type)
202	}
203	
204	fn new_200_with_text (_body : impl Into<B>) -> Self {
205		Self::new_200_with_body (_body, Some (ContentType::Text))
206	}
207	
208	fn new_200_with_html (_body : impl Into<B>) -> Self {
209		Self::new_200_with_body (_body, Some (ContentType::Html))
210	}
211	
212	fn new_200 () -> Self where B : From<&'static str> {
213		Self::new_with_status_and_body (consts::OK, "OK\n", Some (ContentType::Text))
214	}
215	
216	fn new_301 (_location : impl Into<HeaderValue>) -> Self where B : Default {
217		Self::new_redirect_with_code (consts::MOVED_PERMANENTLY, _location)
218	}
219	
220	fn new_302 (_location : impl Into<HeaderValue>) -> Self where B : Default {
221		Self::new_redirect_with_code (consts::FOUND, _location)
222	}
223	
224	fn new_303 (_location : impl Into<HeaderValue>) -> Self where B : Default {
225		Self::new_redirect_with_code (consts::SEE_OTHER, _location)
226	}
227	
228	fn new_307 (_location : impl Into<HeaderValue>) -> Self where B : Default {
229		Self::new_redirect_with_code (consts::TEMPORARY_REDIRECT, _location)
230	}
231	
232	fn new_308 (_location : impl Into<HeaderValue>) -> Self where B : Default {
233		Self::new_redirect_with_code (consts::PERMANENT_REDIRECT, _location)
234	}
235	
236	fn new_301_str_static (_location : &'static str) -> Self where B : Default {
237		Self::new_301 (HeaderValue::from_static (_location))
238	}
239	
240	fn new_302_str_static (_location : &'static str) -> Self where B : Default {
241		Self::new_302 (HeaderValue::from_static (_location))
242	}
243	
244	fn new_303_str_static (_location : &'static str) -> Self where B : Default {
245		Self::new_303 (HeaderValue::from_static (_location))
246	}
247	
248	fn new_307_str_static (_location : &'static str) -> Self where B : Default {
249		Self::new_307 (HeaderValue::from_static (_location))
250	}
251	
252	fn new_308_str_static (_location : &'static str) -> Self where B : Default {
253		Self::new_308 (HeaderValue::from_static (_location))
254	}
255	
256	fn new_301_string (_location : String) -> Self where B : Default {
257		Self::new_301 (HeaderValue::try_from (_location) .or_panic (0x15f9b93c))
258	}
259	
260	fn new_302_string (_location : String) -> Self where B : Default {
261		Self::new_302 (HeaderValue::try_from (_location) .or_panic (0x0a94e02d))
262	}
263	
264	fn new_303_string (_location : String) -> Self where B : Default {
265		Self::new_303 (HeaderValue::try_from (_location) .or_panic (0xa87f95a7))
266	}
267	
268	fn new_307_string (_location : String) -> Self where B : Default {
269		Self::new_307 (HeaderValue::try_from (_location) .or_panic (0xd0e3f0f9))
270	}
271	
272	fn new_308_string (_location : String) -> Self where B : Default {
273		Self::new_308 (HeaderValue::try_from (_location) .or_panic (0x69839071))
274	}
275	
276	fn new_redirect_with_code (_status : StatusCode, _location : impl Into<HeaderValue>) -> Self where B : Default {
277		let mut _response = Self::new_with_status (_status);
278		_response.set_header (consts::LOCATION, _location);
279		_response
280	}
281	
282	fn new_404 () -> Self where B : From<&'static str> {
283		Self::new_with_status_and_body (consts::NOT_FOUND, "404\n", Some (ContentType::Text))
284	}
285	
286	fn new_method_not_allowed () -> Self where B : From<&'static str> {
287		Self::new_with_status_and_body (consts::METHOD_NOT_ALLOWED, "method-not-allowed\n", Some (ContentType::Text))
288	}
289	
290	fn ok <E> (self) -> Result<Self, E> {
291		Ok (self)
292	}
293	
294	fn ok_0 (self) -> Result<Self, ServerError> {
295		Ok (self)
296	}
297	
298	fn ready <E> (self) -> future::Ready<Result<Self, E>> {
299		future::ready (Ok (self))
300	}
301	
302	fn ready_0 (self) -> future::Ready<Result<Self, ServerError>> {
303		future::ready (Ok (self))
304	}
305}
306
307
308#[ cfg (feature = "hss-extensions") ]
309impl ResponseExtBuild<Body> for Response<Body> {
310	
311	fn new_with_status_and_body (_status : StatusCode, _body : impl Into<Body>, _content_type : Option<impl Into<HeaderValue>>) -> Self {
312		let mut _response = Response::new (_body.into ());
313		_response.set_status (_status);
314		if let Some (_content_type) = _content_type {
315			_response.set_content_type (_content_type);
316		}
317		_response
318	}
319}
320
321
322
323
324#[ cfg (feature = "hss-extensions") ]
325#[ cfg (feature = "tokio--rt") ]
326pub trait BodyExt {
327	
328	fn consume_into_vec (&mut self, _buffer : &mut Vec<u8>, _runtime : Option<&Runtime>) -> ServerResult;
329	
330	fn consume_to_vec (&mut self, _runtime : Option<&Runtime>) -> ServerResult<Vec<u8>> {
331		let mut _buffer = Vec::new ();
332		self.consume_into_vec (&mut _buffer, _runtime) ?;
333		Ok (_buffer)
334	}
335}
336
337
338#[ cfg (feature = "hss-extensions") ]
339#[ cfg (feature = "tokio--rt") ]
340impl <B> BodyExt for B
341	where
342		B : BodyTrait<Data = Bytes> + Send + Sync + 'static + Unpin,
343		B::Error : Error + Send + Sync + 'static,
344{
345	fn consume_into_vec (&mut self, _buffer : &mut Vec<u8>, _runtime : Option<&Runtime>) -> ServerResult {
346		
347		_buffer.reserve (BodyTrait::size_hint (self) .lower () as usize);
348		
349		let _runtime_0 = if _runtime.is_none () {
350			Some (tokio::RuntimeBuilder::new_current_thread () .build () .or_wrap (0x6d0d289e) ?)
351		} else {
352			None
353		};
354		
355		let _runtime = _runtime.or (_runtime_0.as_ref ()) .infallible (0x022bb6d6);
356		
357		loop {
358			let _next = _runtime.block_on (self.data ());
359			let _next = if let Some (_next) = _next {
360				_next
361			} else {
362				break;
363			};
364			let mut _data = _next.or_wrap (0x401ac565) ?;
365			while _data.remaining () > 0 {
366				let _chunk = _data.chunk ();
367				_buffer.extend (_chunk);
368				let _chunk_size = _chunk.len ();
369				_data.advance (_chunk_size);
370			}
371		}
372		
373		Ok (())
374	}
375}
376